dhcpv4.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143
  1. /**
  2. * Copyright (C) 2012-2013 Steven Barth <steven@midlink.org>
  3. * Copyright (C) 2016 Hans Dedecker <dedeckeh@gmail.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License v2 as published by
  7. * the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. *
  15. */
  16. #include <time.h>
  17. #include <errno.h>
  18. #include <fcntl.h>
  19. #include <unistd.h>
  20. #include <stddef.h>
  21. #include <stdlib.h>
  22. #include <resolv.h>
  23. #include <limits.h>
  24. #include <net/if.h>
  25. #include <net/if_arp.h>
  26. #include <netinet/ip.h>
  27. #include <sys/ioctl.h>
  28. #include <sys/timerfd.h>
  29. #include <arpa/inet.h>
  30. #include <libubox/md5.h>
  31. #include "odhcpd.h"
  32. #include "dhcpv4.h"
  33. #include "dhcpv6.h"
  34. static void dhcpv4_netevent_cb(unsigned long event, struct netevent_handler_info *info);
  35. static int setup_dhcpv4_addresses(struct interface *iface);
  36. static void update_static_assignments(struct interface *iface);
  37. static bool addr_is_fr_ip(struct interface *iface, struct in_addr *addr);
  38. static void valid_until_cb(struct uloop_timeout *event);
  39. static void handle_addrlist_change(struct interface *iface);
  40. static void free_dhcpv4_assignment(struct dhcpv4_assignment *a);
  41. static void dhcpv4_fr_start(struct dhcpv4_assignment *a);
  42. static void dhcpv4_fr_rand_delay(struct dhcpv4_assignment *a);
  43. static void dhcpv4_fr_stop(struct dhcpv4_assignment *a);
  44. static void handle_dhcpv4(void *addr, void *data, size_t len,
  45. struct interface *iface, void *dest_addr);
  46. static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface,
  47. enum dhcpv4_msg msg, const uint8_t *mac, const uint32_t reqaddr,
  48. uint32_t *leasetime, const char *hostname, const size_t hostname_len,
  49. const bool accept_fr_nonce, bool *incl_fr_opt, uint32_t *fr_serverid);
  50. static struct netevent_handler dhcpv4_netevent_handler = { .cb = dhcpv4_netevent_cb, };
  51. static struct uloop_timeout valid_until_timeout = {.cb = valid_until_cb};
  52. static uint32_t serial = 0;
  53. struct odhcpd_ref_ip {
  54. struct list_head head;
  55. int ref_cnt;
  56. struct odhcpd_ipaddr addr;
  57. };
  58. /* Create socket and register events */
  59. int dhcpv4_init(void)
  60. {
  61. uloop_timeout_set(&valid_until_timeout, 1000);
  62. netlink_add_netevent_handler(&dhcpv4_netevent_handler);
  63. return 0;
  64. }
  65. int dhcpv4_setup_interface(struct interface *iface, bool enable)
  66. {
  67. int ret = 0;
  68. if (iface->dhcpv4_event.uloop.fd > 0) {
  69. uloop_fd_delete(&iface->dhcpv4_event.uloop);
  70. close(iface->dhcpv4_event.uloop.fd);
  71. iface->dhcpv4_event.uloop.fd = -1;
  72. }
  73. if (iface->dhcpv4 && enable) {
  74. struct sockaddr_in bind_addr = {AF_INET, htons(DHCPV4_SERVER_PORT),
  75. {INADDR_ANY}, {0}};
  76. int val = 1;
  77. if (!iface->dhcpv4_assignments.next)
  78. INIT_LIST_HEAD(&iface->dhcpv4_assignments);
  79. if (!iface->dhcpv4_fr_ips.next)
  80. INIT_LIST_HEAD(&iface->dhcpv4_fr_ips);
  81. iface->dhcpv4_event.uloop.fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
  82. if (iface->dhcpv4_event.uloop.fd < 0) {
  83. syslog(LOG_ERR, "socket(AF_INET): %m");
  84. ret = -1;
  85. goto out;
  86. }
  87. /* Basic IPv4 configuration */
  88. if (setsockopt(iface->dhcpv4_event.uloop.fd, SOL_SOCKET, SO_REUSEADDR,
  89. &val, sizeof(val)) < 0) {
  90. syslog(LOG_ERR, "setsockopt(SO_REUSEADDR): %m");
  91. ret = -1;
  92. goto out;
  93. }
  94. if (setsockopt(iface->dhcpv4_event.uloop.fd, SOL_SOCKET, SO_BROADCAST,
  95. &val, sizeof(val)) < 0) {
  96. syslog(LOG_ERR, "setsockopt(SO_BROADCAST): %m");
  97. ret = -1;
  98. goto out;
  99. }
  100. if (setsockopt(iface->dhcpv4_event.uloop.fd, IPPROTO_IP, IP_PKTINFO,
  101. &val, sizeof(val)) < 0) {
  102. syslog(LOG_ERR, "setsockopt(IP_PKTINFO): %m");
  103. ret = -1;
  104. goto out;
  105. }
  106. val = IPTOS_PREC_INTERNETCONTROL;
  107. if (setsockopt(iface->dhcpv4_event.uloop.fd, IPPROTO_IP, IP_TOS,
  108. &val, sizeof(val)) < 0) {
  109. syslog(LOG_ERR, "setsockopt(IP_TOS): %m");
  110. ret = -1;
  111. goto out;
  112. }
  113. val = IP_PMTUDISC_DONT;
  114. if (setsockopt(iface->dhcpv4_event.uloop.fd, IPPROTO_IP, IP_MTU_DISCOVER,
  115. &val, sizeof(val)) < 0) {
  116. syslog(LOG_ERR, "setsockopt(IP_MTU_DISCOVER): %m");
  117. ret = -1;
  118. goto out;
  119. }
  120. if (setsockopt(iface->dhcpv4_event.uloop.fd, SOL_SOCKET, SO_BINDTODEVICE,
  121. iface->ifname, strlen(iface->ifname)) < 0) {
  122. syslog(LOG_ERR, "setsockopt(SO_BINDTODEVICE): %m");
  123. ret = -1;
  124. goto out;
  125. }
  126. if (bind(iface->dhcpv4_event.uloop.fd, (struct sockaddr*)&bind_addr,
  127. sizeof(bind_addr)) < 0) {
  128. syslog(LOG_ERR, "bind(): %m");
  129. ret = -1;
  130. goto out;
  131. }
  132. if (setup_dhcpv4_addresses(iface) < 0) {
  133. ret = -1;
  134. goto out;
  135. }
  136. iface->dhcpv4_event.handle_dgram = handle_dhcpv4;
  137. odhcpd_register(&iface->dhcpv4_event);
  138. update_static_assignments(iface);
  139. } else if (iface->dhcpv4_assignments.next) {
  140. while (!list_empty(&iface->dhcpv4_assignments))
  141. free_dhcpv4_assignment(list_first_entry(&iface->dhcpv4_assignments,
  142. struct dhcpv4_assignment, head));
  143. }
  144. out:
  145. if (ret < 0 && iface->dhcpv4_event.uloop.fd > 0) {
  146. close(iface->dhcpv4_event.uloop.fd);
  147. iface->dhcpv4_event.uloop.fd = -1;
  148. }
  149. return ret;
  150. }
  151. static void dhcpv4_netevent_cb(unsigned long event, struct netevent_handler_info *info)
  152. {
  153. struct interface *iface = info->iface;
  154. if (!iface || iface->dhcpv4 == MODE_DISABLED)
  155. return;
  156. switch (event) {
  157. case NETEV_IFINDEX_CHANGE:
  158. dhcpv4_setup_interface(iface, true);
  159. break;
  160. case NETEV_ADDRLIST_CHANGE:
  161. handle_addrlist_change(iface);
  162. break;
  163. default:
  164. break;
  165. }
  166. }
  167. static struct dhcpv4_assignment *find_assignment_by_hwaddr(struct interface *iface, const uint8_t *hwaddr)
  168. {
  169. struct dhcpv4_assignment *a;
  170. list_for_each_entry(a, &iface->dhcpv4_assignments, head)
  171. if (!memcmp(a->hwaddr, hwaddr, 6))
  172. return a;
  173. return NULL;
  174. }
  175. static struct dhcpv4_assignment *find_assignment_by_addr(struct interface *iface, const uint32_t addr)
  176. {
  177. struct dhcpv4_assignment *a;
  178. list_for_each_entry(a, &iface->dhcpv4_assignments, head)
  179. if (a->addr == addr)
  180. return a;
  181. return NULL;
  182. }
  183. static int setup_dhcpv4_addresses(struct interface *iface)
  184. {
  185. iface->dhcpv4_start_ip.s_addr = INADDR_ANY;
  186. iface->dhcpv4_end_ip.s_addr = INADDR_ANY;
  187. iface->dhcpv4_local.s_addr = INADDR_ANY;
  188. iface->dhcpv4_bcast.s_addr = INADDR_ANY;
  189. iface->dhcpv4_mask.s_addr = INADDR_ANY;
  190. /* Sanity checks */
  191. if (iface->dhcpv4_start.s_addr & htonl(0xffff0000) ||
  192. iface->dhcpv4_end.s_addr & htonl(0xffff0000) ||
  193. ntohl(iface->dhcpv4_start.s_addr) > ntohl(iface->dhcpv4_end.s_addr)) {
  194. syslog(LOG_ERR, "Invalid DHCP range for %s", iface->name);
  195. return -1;
  196. }
  197. if (!iface->addr4_len) {
  198. syslog(LOG_WARNING, "No network(s) available on %s", iface->name);
  199. return -1;
  200. }
  201. uint32_t start = ntohl(iface->dhcpv4_start.s_addr);
  202. uint32_t end = ntohl(iface->dhcpv4_end.s_addr);
  203. for (size_t i = 0; i < iface->addr4_len && start && end; i++) {
  204. struct in_addr *addr = &iface->addr4[i].addr.in;
  205. struct in_addr mask;
  206. if (addr_is_fr_ip(iface, addr))
  207. continue;
  208. odhcpd_bitlen2netmask(false, iface->addr4[i].prefix, &mask);
  209. if ((start & ntohl(~mask.s_addr)) == start &&
  210. (end & ntohl(~mask.s_addr)) == end) {
  211. iface->dhcpv4_start_ip.s_addr = htonl(start) |
  212. (addr->s_addr & mask.s_addr);
  213. iface->dhcpv4_end_ip.s_addr = htonl(end) |
  214. (addr->s_addr & mask.s_addr);
  215. iface->dhcpv4_local = *addr;
  216. iface->dhcpv4_bcast = iface->addr4[i].broadcast;
  217. iface->dhcpv4_mask = mask;
  218. return 0;
  219. }
  220. }
  221. /* Don't allocate IP range for subnets bigger than 28 */
  222. if (iface->addr4[0].prefix > 28) {
  223. syslog(LOG_WARNING, "Auto allocation of DHCP range fails on %s", iface->name);
  224. return -1;
  225. }
  226. iface->dhcpv4_local = iface->addr4[0].addr.in;
  227. iface->dhcpv4_bcast = iface->addr4[0].broadcast;
  228. odhcpd_bitlen2netmask(false, iface->addr4[0].prefix, &iface->dhcpv4_mask);
  229. end = start = iface->dhcpv4_local.s_addr & iface->dhcpv4_mask.s_addr;
  230. /* Auto allocate ranges */
  231. if (ntohl(iface->dhcpv4_mask.s_addr) <= 0xffffff00) {
  232. iface->dhcpv4_start_ip.s_addr = start | htonl(100);
  233. iface->dhcpv4_end_ip.s_addr = end | htonl(250);
  234. } else if (ntohl(iface->dhcpv4_mask.s_addr) <= 0xffffffc0) {
  235. iface->dhcpv4_start_ip.s_addr = start | htonl(10);
  236. iface->dhcpv4_end_ip.s_addr = end | htonl(60);
  237. } else if (ntohl(iface->dhcpv4_mask.s_addr) <= 0xffffffe0) {
  238. iface->dhcpv4_start_ip.s_addr = start | htonl(10);
  239. iface->dhcpv4_end_ip.s_addr = end | htonl(30);
  240. } else {
  241. iface->dhcpv4_start_ip.s_addr = start | htonl(3);
  242. iface->dhcpv4_end_ip.s_addr = end | htonl(12);
  243. }
  244. return 0;
  245. }
  246. static void update_static_assignments(struct interface *iface)
  247. {
  248. struct dhcpv4_assignment *a, *c;
  249. /* Cleanup static entries not belonging to the network */
  250. list_for_each_entry_safe(a, c, &iface->dhcpv4_assignments, head) {
  251. if ((a->flags & OAF_STATIC) &&
  252. ((a->addr & iface->dhcpv4_mask.s_addr) !=
  253. (iface->dhcpv4_start.s_addr & iface->dhcpv4_mask.s_addr)))
  254. free_dhcpv4_assignment(a);
  255. }
  256. /* Parse static entries */
  257. struct lease *lease;
  258. list_for_each_entry(lease, &leases, head) {
  259. if ((iface->dhcpv4_start_ip.s_addr & iface->dhcpv4_mask.s_addr) !=
  260. (lease->ipaddr.s_addr & iface->dhcpv4_mask.s_addr)) {
  261. continue;
  262. }
  263. a = find_assignment_by_hwaddr(iface, lease->mac.ether_addr_octet);
  264. if (!a) {
  265. /* Check if there's an assignment with the specified IP address */
  266. if (find_assignment_by_addr(iface, lease->ipaddr.s_addr))
  267. continue;
  268. /* Construct entry */
  269. a = calloc(1, sizeof(*a));
  270. if (!a) {
  271. syslog(LOG_ERR, "Calloc failed for static lease on %s", iface->name);
  272. continue;
  273. }
  274. memcpy(a->hwaddr, lease->mac.ether_addr_octet, sizeof(a->hwaddr));
  275. }
  276. a->leasetime = lease->dhcpv4_leasetime;
  277. a->addr = lease->ipaddr.s_addr;
  278. /* Static assignment */
  279. a->flags |= OAF_STATIC;
  280. /* Infinite valid */
  281. a->valid_until = 0;
  282. a->iface = iface;
  283. if (lease->hostname[0]) {
  284. free(a->hostname);
  285. a->hostname = strdup(lease->hostname);
  286. }
  287. /* Assign to all interfaces */
  288. list_for_each_entry(c, &iface->dhcpv4_assignments, head) {
  289. if (ntohl(c->addr) > ntohl(a->addr)) {
  290. list_add_tail(&a->head, &c->head);
  291. break;
  292. }
  293. }
  294. if (&c->head == &iface->dhcpv4_assignments)
  295. list_add(&a->head, &iface->dhcpv4_assignments);
  296. }
  297. }
  298. static void inc_ref_cnt_ip(struct odhcpd_ref_ip **ptr, struct odhcpd_ref_ip *ip)
  299. {
  300. *ptr = ip;
  301. ip->ref_cnt++;
  302. }
  303. static void decr_ref_cnt_ip(struct odhcpd_ref_ip **ptr, struct interface *iface)
  304. {
  305. struct odhcpd_ref_ip *ip = *ptr;
  306. if (--ip->ref_cnt == 0) {
  307. netlink_setup_addr(&ip->addr, iface->ifindex, false, false);
  308. list_del(&ip->head);
  309. free(ip);
  310. }
  311. *ptr = NULL;
  312. }
  313. static bool addr_is_fr_ip(struct interface *iface, struct in_addr *addr)
  314. {
  315. struct odhcpd_ref_ip *p;
  316. list_for_each_entry(p, &iface->dhcpv4_fr_ips, head) {
  317. if (addr->s_addr == p->addr.addr.in.s_addr)
  318. return true;
  319. }
  320. return false;
  321. }
  322. static bool leases_require_fr(struct interface *iface, struct odhcpd_ipaddr *addr,
  323. uint32_t mask)
  324. {
  325. struct dhcpv4_assignment *a = NULL;
  326. struct odhcpd_ref_ip *fr_ip = NULL;
  327. list_for_each_entry(a, &iface->dhcpv4_assignments, head) {
  328. if ((a->accept_fr_nonce || iface->dhcpv4_forcereconf) &&
  329. !a->fr_ip &&
  330. ((a->addr & mask) == (addr->addr.in.s_addr & mask))) {
  331. if (!fr_ip) {
  332. fr_ip = calloc(1, sizeof(*fr_ip));
  333. if (!fr_ip)
  334. break;
  335. list_add(&fr_ip->head, &iface->dhcpv4_fr_ips);
  336. fr_ip->addr = *addr;
  337. }
  338. inc_ref_cnt_ip(&a->fr_ip, fr_ip);
  339. }
  340. }
  341. return fr_ip ? true : false;
  342. }
  343. static void valid_until_cb(struct uloop_timeout *event)
  344. {
  345. struct interface *iface;
  346. time_t now = odhcpd_time();
  347. avl_for_each_element(&interfaces, iface, avl) {
  348. if (iface->dhcpv4 != MODE_SERVER || iface->dhcpv4_assignments.next == NULL)
  349. continue;
  350. struct dhcpv4_assignment *a, *n;
  351. list_for_each_entry_safe(a, n, &iface->dhcpv4_assignments, head) {
  352. if (!INFINITE_VALID(a->valid_until) && a->valid_until < now)
  353. free_dhcpv4_assignment(a);
  354. }
  355. }
  356. uloop_timeout_set(event, 1000);
  357. }
  358. static void handle_addrlist_change(struct interface *iface)
  359. {
  360. struct odhcpd_ipaddr ip;
  361. struct odhcpd_ref_ip *a;
  362. struct dhcpv4_assignment *c;
  363. uint32_t mask = iface->dhcpv4_mask.s_addr;
  364. memset(&ip, 0, sizeof(ip));
  365. ip.addr.in = iface->dhcpv4_local;
  366. ip.prefix = odhcpd_netmask2bitlen(false, &iface->dhcpv4_mask);
  367. ip.broadcast = iface->dhcpv4_bcast;
  368. setup_dhcpv4_addresses(iface);
  369. if ((ip.addr.in.s_addr & mask) ==
  370. (iface->dhcpv4_local.s_addr & iface->dhcpv4_mask.s_addr))
  371. return;
  372. if (ip.addr.in.s_addr && !leases_require_fr(iface, &ip, mask))
  373. return;
  374. if (iface->dhcpv4_local.s_addr == INADDR_ANY || list_empty(&iface->dhcpv4_fr_ips))
  375. return;
  376. a = list_first_entry(&iface->dhcpv4_fr_ips, struct odhcpd_ref_ip, head);
  377. if (netlink_setup_addr(&a->addr, iface->ifindex, false, true)) {
  378. syslog(LOG_ERR, "Failed to add ip address on %s", iface->name);
  379. return;
  380. }
  381. list_for_each_entry(c, &iface->dhcpv4_assignments, head) {
  382. if ((c->flags & OAF_BOUND) && c->fr_ip && !c->fr_cnt) {
  383. if (c->accept_fr_nonce || iface->dhcpv4_forcereconf)
  384. dhcpv4_fr_rand_delay(c);
  385. else
  386. dhcpv4_fr_stop(c);
  387. }
  388. }
  389. }
  390. static char *dhcpv4_msg_to_string(uint8_t reqmsg)
  391. {
  392. switch (reqmsg) {
  393. case (DHCPV4_MSG_DISCOVER):
  394. return "DHCPV4_MSG_DISCOVER";
  395. case (DHCPV4_MSG_OFFER):
  396. return "DHCPV4_MSG_OFFER";
  397. case (DHCPV4_MSG_REQUEST):
  398. return "DHCPV4_MSG_REQUEST";
  399. case (DHCPV4_MSG_DECLINE):
  400. return "DHCPV4_MSG_DECLINE";
  401. case (DHCPV4_MSG_ACK):
  402. return "DHCPV4_MSG_ACK";
  403. case (DHCPV4_MSG_NAK):
  404. return "DHCPV4_MSG_NAK";
  405. case (DHCPV4_MSG_RELEASE):
  406. return "DHCPV4_MSG_RELEASE";
  407. case (DHCPV4_MSG_INFORM):
  408. return "DHCPV4_MSG_INFORM";
  409. case (DHCPV4_MSG_FORCERENEW):
  410. return "DHCPV4_MSG_FORCERENEW";
  411. default:
  412. return "UNKNOWN";
  413. }
  414. }
  415. static void free_dhcpv4_assignment(struct dhcpv4_assignment *a)
  416. {
  417. if (a->head.next)
  418. list_del(&a->head);
  419. if (a->fr_ip)
  420. dhcpv4_fr_stop(a);
  421. free(a->hostname);
  422. free(a);
  423. }
  424. static void dhcpv4_put(struct dhcpv4_message *msg, uint8_t **cookie,
  425. uint8_t type, uint8_t len, const void *data)
  426. {
  427. uint8_t *c = *cookie;
  428. uint8_t *end = (uint8_t *)msg + sizeof(*msg);
  429. if (*cookie + 2 + len > end)
  430. return;
  431. *c++ = type;
  432. *c++ = len;
  433. memcpy(c, data, len);
  434. *cookie = c + len;
  435. }
  436. static void dhcpv4_fr_send(struct dhcpv4_assignment *a)
  437. {
  438. struct dhcpv4_message fr_msg = {
  439. .op = DHCPV4_BOOTREPLY,
  440. .htype = 1,
  441. .hlen = 6,
  442. .hops = 0,
  443. .secs = 0,
  444. .flags = 0,
  445. .ciaddr = {INADDR_ANY},
  446. .yiaddr = {INADDR_ANY},
  447. .siaddr = {INADDR_ANY},
  448. .giaddr = {INADDR_ANY},
  449. .chaddr = {0},
  450. .sname = {0},
  451. .file = {0},
  452. };
  453. struct dhcpv4_auth_forcerenew *auth_o, auth = {
  454. .protocol = 3,
  455. .algorithm = 1,
  456. .rdm = 0,
  457. .replay = {htonl(time(NULL)), htonl(++serial)},
  458. .type = 2,
  459. .key = {0},
  460. };
  461. struct interface *iface = a->iface;
  462. odhcpd_urandom(&fr_msg.xid, sizeof(fr_msg.xid));
  463. memcpy(fr_msg.chaddr, a->hwaddr, fr_msg.hlen);
  464. fr_msg.options[0] = 0x63;
  465. fr_msg.options[1] = 0x82;
  466. fr_msg.options[2] = 0x53;
  467. fr_msg.options[3] = 0x63;
  468. uint8_t *cookie = &fr_msg.options[4];
  469. uint8_t msg = DHCPV4_MSG_FORCERENEW;
  470. dhcpv4_put(&fr_msg, &cookie, DHCPV4_OPT_MESSAGE, 1, &msg);
  471. if (a->accept_fr_nonce) {
  472. dhcpv4_put(&fr_msg, &cookie, DHCPV4_OPT_AUTHENTICATION, sizeof(auth), &auth);
  473. auth_o = (struct dhcpv4_auth_forcerenew *)(cookie - sizeof(auth));
  474. dhcpv4_put(&fr_msg, &cookie, DHCPV4_OPT_END, 0, NULL);
  475. md5_ctx_t md5;
  476. uint8_t secretbytes[64];
  477. memset(secretbytes, 0, sizeof(secretbytes));
  478. memcpy(secretbytes, a->key, sizeof(a->key));
  479. for (size_t i = 0; i < sizeof(secretbytes); ++i)
  480. secretbytes[i] ^= 0x36;
  481. md5_begin(&md5);
  482. md5_hash(secretbytes, sizeof(secretbytes), &md5);
  483. md5_hash(&fr_msg, sizeof(fr_msg), &md5);
  484. md5_end(auth_o->key, &md5);
  485. for (size_t i = 0; i < sizeof(secretbytes); ++i) {
  486. secretbytes[i] ^= 0x36;
  487. secretbytes[i] ^= 0x5c;
  488. }
  489. md5_begin(&md5);
  490. md5_hash(secretbytes, sizeof(secretbytes), &md5);
  491. md5_hash(auth_o->key, sizeof(auth_o->key), &md5);
  492. md5_end(auth_o->key, &md5);
  493. } else {
  494. dhcpv4_put(&fr_msg, &cookie, DHCPV4_OPT_SERVERID, 4,
  495. &a->fr_ip->addr.addr.in.s_addr);
  496. dhcpv4_put(&fr_msg, &cookie, DHCPV4_OPT_END, 0, NULL);
  497. }
  498. struct sockaddr_in dest;
  499. memset(&dest, 0, sizeof(dest));
  500. dest.sin_family = AF_INET;
  501. dest.sin_port = htons(DHCPV4_CLIENT_PORT);
  502. dest.sin_addr.s_addr = a->addr;
  503. if (sendto(iface->dhcpv4_event.uloop.fd, &fr_msg, sizeof(fr_msg),
  504. MSG_DONTWAIT, (struct sockaddr*)&dest, sizeof(dest)) < 0)
  505. syslog(LOG_ERR, "Failed to send %s to %s - %s: %m", dhcpv4_msg_to_string(msg),
  506. odhcpd_print_mac(a->hwaddr, sizeof(a->hwaddr)), inet_ntoa(dest.sin_addr));
  507. else
  508. syslog(LOG_WARNING, "Sent %s to %s - %s", dhcpv4_msg_to_string(msg),
  509. odhcpd_print_mac(a->hwaddr, sizeof(a->hwaddr)), inet_ntoa(dest.sin_addr));
  510. }
  511. static void dhcpv4_fr_timer(struct uloop_timeout *event)
  512. {
  513. struct dhcpv4_assignment *a = container_of(event, struct dhcpv4_assignment, fr_timer);
  514. if (a->fr_cnt > 0 && a->fr_cnt < 8) {
  515. dhcpv4_fr_send(a);
  516. uloop_timeout_set(&a->fr_timer, 1000 << a->fr_cnt);
  517. a->fr_cnt++;
  518. } else
  519. dhcpv4_fr_stop(a);
  520. }
  521. static void dhcpv4_fr_start(struct dhcpv4_assignment *a)
  522. {
  523. uloop_timeout_set(&a->fr_timer, 1000 << a->fr_cnt);
  524. a->fr_timer.cb = dhcpv4_fr_timer;
  525. a->fr_cnt++;
  526. dhcpv4_fr_send(a);
  527. }
  528. static void dhcpv4_fr_delay_timer(struct uloop_timeout *event)
  529. {
  530. struct dhcpv4_assignment *a = container_of(event, struct dhcpv4_assignment, fr_timer);
  531. struct interface *iface = a->iface;
  532. (iface->dhcpv4_event.uloop.fd == -1 ? dhcpv4_fr_rand_delay(a) : dhcpv4_fr_start(a));
  533. }
  534. static void dhcpv4_fr_rand_delay(struct dhcpv4_assignment *a)
  535. {
  536. #define MIN_DELAY 500
  537. #define MAX_FUZZ 500
  538. int msecs;
  539. odhcpd_urandom(&msecs, sizeof(msecs));
  540. msecs = labs(msecs)%MAX_FUZZ + MIN_DELAY;
  541. uloop_timeout_set(&a->fr_timer, msecs);
  542. a->fr_timer.cb = dhcpv4_fr_delay_timer;
  543. }
  544. static void dhcpv4_fr_stop(struct dhcpv4_assignment *a)
  545. {
  546. uloop_timeout_cancel(&a->fr_timer);
  547. decr_ref_cnt_ip(&a->fr_ip, a->iface);
  548. a->fr_cnt = 0;
  549. a->fr_timer.cb = NULL;
  550. }
  551. /* Handler for DHCPv4 messages */
  552. static void handle_dhcpv4(void *addr, void *data, size_t len,
  553. struct interface *iface, _unused void *dest_addr)
  554. {
  555. if (!iface->dhcpv4)
  556. return;
  557. struct dhcpv4_message *req = data;
  558. if (len < offsetof(struct dhcpv4_message, options) + 4 ||
  559. req->op != DHCPV4_BOOTREQUEST || req->hlen != 6)
  560. return;
  561. syslog(LOG_NOTICE, "Got DHCPv4 request on %s", iface->name);
  562. if (!iface->dhcpv4_start_ip.s_addr && !iface->dhcpv4_end_ip.s_addr) {
  563. syslog(LOG_WARNING, "No DHCP range available on %s", iface->name);
  564. return;
  565. }
  566. int sock = iface->dhcpv4_event.uloop.fd;
  567. struct dhcpv4_message reply = {
  568. .op = DHCPV4_BOOTREPLY,
  569. .htype = req->htype,
  570. .hlen = req->hlen,
  571. .hops = 0,
  572. .xid = req->xid,
  573. .secs = 0,
  574. .flags = req->flags,
  575. .ciaddr = {INADDR_ANY},
  576. .giaddr = req->giaddr,
  577. .siaddr = iface->dhcpv4_local,
  578. };
  579. memcpy(reply.chaddr, req->chaddr, sizeof(reply.chaddr));
  580. reply.options[0] = 0x63;
  581. reply.options[1] = 0x82;
  582. reply.options[2] = 0x53;
  583. reply.options[3] = 0x63;
  584. uint8_t *cookie = &reply.options[4];
  585. uint8_t reqmsg = DHCPV4_MSG_REQUEST;
  586. uint8_t msg = DHCPV4_MSG_ACK;
  587. uint32_t reqaddr = INADDR_ANY;
  588. uint32_t leasetime = 0;
  589. size_t hostname_len = 0;
  590. char hostname[256];
  591. bool accept_fr_nonce = false;
  592. bool incl_fr_opt = false;
  593. uint8_t *start = &req->options[4];
  594. uint8_t *end = ((uint8_t*)data) + len;
  595. struct dhcpv4_option *opt;
  596. dhcpv4_for_each_option(start, end, opt) {
  597. if (opt->type == DHCPV4_OPT_MESSAGE && opt->len == 1)
  598. reqmsg = opt->data[0];
  599. else if (opt->type == DHCPV4_OPT_HOSTNAME && opt->len > 0) {
  600. hostname_len = opt->len;
  601. memcpy(hostname, opt->data, hostname_len);
  602. hostname[hostname_len] = 0;
  603. } else if (opt->type == DHCPV4_OPT_IPADDRESS && opt->len == 4)
  604. memcpy(&reqaddr, opt->data, 4);
  605. else if (opt->type == DHCPV4_OPT_SERVERID && opt->len == 4) {
  606. if (memcmp(opt->data, &iface->dhcpv4_local, 4))
  607. return;
  608. } else if (iface->filter_class && opt->type == DHCPV4_OPT_USER_CLASS) {
  609. uint8_t *c = opt->data, *cend = &opt->data[opt->len];
  610. for (; c < cend && &c[*c] < cend; c = &c[1 + *c]) {
  611. size_t elen = strlen(iface->filter_class);
  612. if (*c == elen && !memcmp(&c[1], iface->filter_class, elen))
  613. return; // Ignore from homenet
  614. }
  615. } else if (opt->type == DHCPV4_OPT_LEASETIME && opt->len == 4)
  616. memcpy(&leasetime, opt->data, 4);
  617. else if (opt->type == DHCPV4_OPT_FORCERENEW_NONCE_CAPABLE && opt->len > 0) {
  618. for (uint8_t i = 0; i < opt->len; i++) {
  619. if (opt->data[i] == 1) {
  620. accept_fr_nonce = true;
  621. break;
  622. }
  623. }
  624. }
  625. }
  626. if (reqmsg != DHCPV4_MSG_DISCOVER && reqmsg != DHCPV4_MSG_REQUEST &&
  627. reqmsg != DHCPV4_MSG_INFORM && reqmsg != DHCPV4_MSG_DECLINE &&
  628. reqmsg != DHCPV4_MSG_RELEASE)
  629. return;
  630. struct dhcpv4_assignment *lease = NULL;
  631. uint32_t serverid = iface->dhcpv4_local.s_addr;
  632. uint32_t fr_serverid = INADDR_ANY;
  633. if (reqmsg != DHCPV4_MSG_INFORM)
  634. lease = dhcpv4_lease(iface, reqmsg, req->chaddr, reqaddr,
  635. &leasetime, hostname, hostname_len,
  636. accept_fr_nonce, &incl_fr_opt, &fr_serverid);
  637. if (!lease) {
  638. if (reqmsg == DHCPV4_MSG_REQUEST)
  639. msg = DHCPV4_MSG_NAK;
  640. else if (reqmsg == DHCPV4_MSG_DISCOVER)
  641. return;
  642. } else if (reqmsg == DHCPV4_MSG_DISCOVER)
  643. msg = DHCPV4_MSG_OFFER;
  644. else if (reqmsg == DHCPV4_MSG_REQUEST &&
  645. ((reqaddr && reqaddr != lease->addr) ||
  646. (req->ciaddr.s_addr && req->ciaddr.s_addr != lease->addr))) {
  647. msg = DHCPV4_MSG_NAK;
  648. /*
  649. * DHCP client requested an IP which we can't offer to him. Probably the
  650. * client changed the network or the network has been changed. The reply
  651. * type is set to DHCPV4_MSG_NAK, because the client should not use that IP.
  652. *
  653. * For modern devices we build an answer that includes a valid IP, like
  654. * a DHCPV4_MSG_ACK. The client will use that IP and doesn't need to
  655. * perform additional DHCP round trips.
  656. *
  657. */
  658. /*
  659. *
  660. * Buggy clients do serverid checking in nack messages; therefore set the
  661. * serverid in nack messages triggered by a previous force renew equal to
  662. * the server id in use at that time by the server
  663. *
  664. */
  665. if (fr_serverid)
  666. serverid = fr_serverid;
  667. if (req->ciaddr.s_addr &&
  668. ((iface->dhcpv4_start_ip.s_addr & iface->dhcpv4_mask.s_addr) !=
  669. (req->ciaddr.s_addr & iface->dhcpv4_mask.s_addr)))
  670. req->ciaddr.s_addr = INADDR_ANY;
  671. }
  672. syslog(LOG_WARNING, "Received %s from %s on %s", dhcpv4_msg_to_string(reqmsg),
  673. odhcpd_print_mac(req->chaddr, req->hlen), iface->name);
  674. #ifdef WITH_UBUS
  675. if (reqmsg == DHCPV4_MSG_RELEASE)
  676. ubus_bcast_dhcp_event("dhcp.release", req->chaddr, req->hlen,
  677. &req->ciaddr, hostname, iface->ifname);
  678. #endif
  679. if (reqmsg == DHCPV4_MSG_DECLINE || reqmsg == DHCPV4_MSG_RELEASE)
  680. return;
  681. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_MESSAGE, 1, &msg);
  682. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_SERVERID, 4, &serverid);
  683. if (lease) {
  684. uint32_t val;
  685. reply.yiaddr.s_addr = lease->addr;
  686. val = htonl(leasetime);
  687. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_LEASETIME, 4, &val);
  688. if (leasetime != UINT32_MAX) {
  689. val = htonl(500 * leasetime / 1000);
  690. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_RENEW, 4, &val);
  691. val = htonl(875 * leasetime / 1000);
  692. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_REBIND, 4, &val);
  693. }
  694. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_NETMASK, 4,
  695. &iface->dhcpv4_mask.s_addr);
  696. if (lease->hostname)
  697. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_HOSTNAME,
  698. strlen(lease->hostname), lease->hostname);
  699. if (iface->dhcpv4_bcast.s_addr != INADDR_ANY)
  700. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_BROADCAST, 4, &iface->dhcpv4_bcast);
  701. if (incl_fr_opt) {
  702. if (reqmsg == DHCPV4_MSG_REQUEST) {
  703. struct dhcpv4_auth_forcerenew auth = {
  704. .protocol = 3,
  705. .algorithm = 1,
  706. .rdm = 0,
  707. .replay = {htonl(time(NULL)), htonl(++serial)},
  708. .type = 1,
  709. .key = {0},
  710. };
  711. memcpy(auth.key, lease->key, sizeof(auth.key));
  712. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_AUTHENTICATION, sizeof(auth), &auth);
  713. } else {
  714. uint8_t one = 1;
  715. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_FORCERENEW_NONCE_CAPABLE,
  716. sizeof(one), &one);
  717. }
  718. }
  719. }
  720. struct ifreq ifr;
  721. memset(&ifr, 0, sizeof(ifr));
  722. strncpy(ifr.ifr_name, iface->ifname, sizeof(ifr.ifr_name) - 1);
  723. if (!ioctl(sock, SIOCGIFMTU, &ifr)) {
  724. uint16_t mtu = htons(ifr.ifr_mtu);
  725. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_MTU, 2, &mtu);
  726. }
  727. if (iface->search && iface->search_len <= 255)
  728. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_SEARCH_DOMAIN,
  729. iface->search_len, iface->search);
  730. else if (!res_init() && _res.dnsrch[0] && _res.dnsrch[0][0]) {
  731. uint8_t search_buf[256];
  732. int len = dn_comp(_res.dnsrch[0], search_buf,
  733. sizeof(search_buf), NULL, NULL);
  734. if (len > 0)
  735. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_SEARCH_DOMAIN,
  736. len, search_buf);
  737. }
  738. if (iface->dhcpv4_router_cnt == 0)
  739. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_ROUTER, 4, &iface->dhcpv4_local);
  740. else
  741. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_ROUTER,
  742. 4 * iface->dhcpv4_router_cnt, iface->dhcpv4_router);
  743. if (iface->dhcpv4_dns_cnt == 0)
  744. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_DNSSERVER, 4, &iface->dhcpv4_local);
  745. else
  746. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_DNSSERVER,
  747. 4 * iface->dhcpv4_dns_cnt, iface->dhcpv4_dns);
  748. dhcpv4_put(&reply, &cookie, DHCPV4_OPT_END, 0, NULL);
  749. struct sockaddr_in dest = *((struct sockaddr_in*)addr);
  750. if (req->giaddr.s_addr) {
  751. /*
  752. * relay agent is configured, send reply to the agent
  753. */
  754. dest.sin_addr = req->giaddr;
  755. dest.sin_port = htons(DHCPV4_SERVER_PORT);
  756. } else if (req->ciaddr.s_addr && req->ciaddr.s_addr != dest.sin_addr.s_addr) {
  757. /*
  758. * client has existing configuration (ciaddr is set) AND this address is
  759. * not the address it used for the dhcp message
  760. */
  761. dest.sin_addr = req->ciaddr;
  762. dest.sin_port = htons(DHCPV4_CLIENT_PORT);
  763. } else if ((ntohs(req->flags) & DHCPV4_FLAG_BROADCAST) ||
  764. req->hlen != reply.hlen || !reply.yiaddr.s_addr) {
  765. /*
  766. * client requests a broadcast reply OR we can't offer an IP
  767. */
  768. dest.sin_addr.s_addr = INADDR_BROADCAST;
  769. dest.sin_port = htons(DHCPV4_CLIENT_PORT);
  770. } else if (!req->ciaddr.s_addr && msg == DHCPV4_MSG_NAK) {
  771. /*
  772. * client has no previous configuration -> no IP, so we need to reply
  773. * with a broadcast packet
  774. */
  775. dest.sin_addr.s_addr = INADDR_BROADCAST;
  776. dest.sin_port = htons(DHCPV4_CLIENT_PORT);
  777. } else {
  778. struct arpreq arp = {.arp_flags = ATF_COM};
  779. /*
  780. * send reply to the newly (in this proccess) allocated IP
  781. */
  782. dest.sin_addr = reply.yiaddr;
  783. dest.sin_port = htons(DHCPV4_CLIENT_PORT);
  784. memcpy(arp.arp_ha.sa_data, req->chaddr, 6);
  785. memcpy(&arp.arp_pa, &dest, sizeof(arp.arp_pa));
  786. memcpy(arp.arp_dev, iface->ifname, sizeof(arp.arp_dev));
  787. if (ioctl(sock, SIOCSARP, &arp) < 0)
  788. syslog(LOG_ERR, "ioctl(SIOCSARP): %m");
  789. }
  790. if (sendto(sock, &reply, sizeof(reply), MSG_DONTWAIT,
  791. (struct sockaddr*)&dest, sizeof(dest)) < 0)
  792. syslog(LOG_ERR, "Failed to send %s to %s - %s: %m",
  793. dhcpv4_msg_to_string(msg),
  794. dest.sin_addr.s_addr == INADDR_BROADCAST ?
  795. "ff:ff:ff:ff:ff:ff": odhcpd_print_mac(req->chaddr, req->hlen),
  796. inet_ntoa(dest.sin_addr));
  797. else
  798. syslog(LOG_ERR, "Sent %s to %s - %s",
  799. dhcpv4_msg_to_string(msg),
  800. dest.sin_addr.s_addr == INADDR_BROADCAST ?
  801. "ff:ff:ff:ff:ff:ff": odhcpd_print_mac(req->chaddr, req->hlen),
  802. inet_ntoa(dest.sin_addr));
  803. #ifdef WITH_UBUS
  804. if (msg == DHCPV4_MSG_ACK)
  805. ubus_bcast_dhcp_event("dhcp.ack", req->chaddr, req->hlen, &reply.yiaddr,
  806. hostname, iface->ifname);
  807. #endif
  808. }
  809. static bool dhcpv4_assign(struct interface *iface,
  810. struct dhcpv4_assignment *assign, uint32_t raddr)
  811. {
  812. uint32_t start = ntohl(iface->dhcpv4_start_ip.s_addr);
  813. uint32_t end = ntohl(iface->dhcpv4_end_ip.s_addr);
  814. uint32_t count = end - start + 1;
  815. /* try to assign the IP the client asked for */
  816. if (start <= ntohl(raddr) && ntohl(raddr) <= end &&
  817. !find_assignment_by_addr(iface, raddr)) {
  818. assign->addr = raddr;
  819. syslog(LOG_INFO, "Assigning the IP the client asked for: %u.%u.%u.%u",
  820. ((uint8_t *)&assign->addr)[0],
  821. ((uint8_t *)&assign->addr)[1],
  822. ((uint8_t *)&assign->addr)[2],
  823. ((uint8_t *)&assign->addr)[3]);
  824. return true;
  825. }
  826. /* Seed RNG with checksum of hwaddress */
  827. uint32_t seed = 0;
  828. for (size_t i = 0; i < sizeof(assign->hwaddr); ++i) {
  829. /* Knuth's multiplicative method */
  830. uint8_t o = assign->hwaddr[i];
  831. seed += (o*2654435761) % UINT32_MAX;
  832. }
  833. srand(seed);
  834. uint32_t try = (((uint32_t)rand()) % count) + start;
  835. if (list_empty(&iface->dhcpv4_assignments)) {
  836. assign->addr = htonl(try);
  837. syslog(LOG_INFO, "Assigning mapped IP (empty list): %u.%u.%u.%u",
  838. ((uint8_t *)&assign->addr)[0],
  839. ((uint8_t *)&assign->addr)[1],
  840. ((uint8_t *)&assign->addr)[2],
  841. ((uint8_t *)&assign->addr)[3]);
  842. return true;
  843. }
  844. for (uint32_t i = 0; i < count; ++i) {
  845. if (!find_assignment_by_addr(iface, htonl(try))) {
  846. /* test was successful: IP address is not assigned, assign it */
  847. assign->addr = htonl(try);
  848. syslog(LOG_DEBUG, "Assigning mapped IP: %u.%u.%u.%u (try %u of %u)",
  849. ((uint8_t *)&assign->addr)[0],
  850. ((uint8_t *)&assign->addr)[1],
  851. ((uint8_t *)&assign->addr)[2],
  852. ((uint8_t *)&assign->addr)[3],
  853. i, count);
  854. return true;
  855. }
  856. try = (((try - start) + 1) % count) + start;
  857. }
  858. syslog(LOG_WARNING, "Can't assign any IP address -> address space is full");
  859. return false;
  860. }
  861. static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface,
  862. enum dhcpv4_msg msg, const uint8_t *mac, const uint32_t reqaddr,
  863. uint32_t *leasetime, const char *hostname, const size_t hostname_len,
  864. const bool accept_fr_nonce, bool *incl_fr_opt, uint32_t *fr_serverid)
  865. {
  866. struct dhcpv4_assignment *a = find_assignment_by_hwaddr(iface, mac);
  867. struct dhcpv4_assignment *lease = NULL;
  868. time_t now = odhcpd_time();
  869. if (a && (a->flags & OAF_BOUND) && a->fr_ip) {
  870. *fr_serverid = a->fr_ip->addr.addr.in.s_addr;
  871. dhcpv4_fr_stop(a);
  872. }
  873. if (msg == DHCPV4_MSG_DISCOVER || msg == DHCPV4_MSG_REQUEST) {
  874. bool assigned = !!a;
  875. if (!a) {
  876. if (!iface->no_dynamic_dhcp) {
  877. /* Create new binding */
  878. a = calloc(1, sizeof(*a));
  879. if (!a) {
  880. syslog(LOG_ERR, "Failed to calloc binding on interface %s",
  881. iface->ifname);
  882. return NULL;
  883. }
  884. memcpy(a->hwaddr, mac, sizeof(a->hwaddr));
  885. /* Don't consider new assignment as infinite */
  886. a->valid_until = now;
  887. assigned = dhcpv4_assign(iface, a, reqaddr);
  888. if (assigned) {
  889. a->iface = iface;
  890. list_add(&a->head, &iface->dhcpv4_assignments);
  891. }
  892. }
  893. } else if ((a->addr & iface->dhcpv4_mask.s_addr) !=
  894. (iface->dhcpv4_start_ip.s_addr & iface->dhcpv4_mask.s_addr)) {
  895. list_del(&a->head);
  896. assigned = dhcpv4_assign(iface, a, reqaddr);
  897. if (assigned)
  898. list_add(&a->head, &iface->dhcpv4_assignments);
  899. }
  900. if (assigned) {
  901. uint32_t my_leasetime;
  902. if (a->leasetime)
  903. my_leasetime = a->leasetime;
  904. else
  905. my_leasetime = iface->dhcpv4_leasetime;
  906. if ((*leasetime == 0) || (my_leasetime < *leasetime))
  907. *leasetime = my_leasetime;
  908. if (msg == DHCPV4_MSG_DISCOVER) {
  909. a->flags &= ~OAF_BOUND;
  910. *incl_fr_opt = accept_fr_nonce;
  911. if (!(a->flags & OAF_STATIC))
  912. a->valid_until = now;
  913. } else {
  914. if (hostname_len > 0) {
  915. a->hostname = realloc(a->hostname, hostname_len + 1);
  916. if (a->hostname) {
  917. memcpy(a->hostname, hostname, hostname_len);
  918. a->hostname[hostname_len] = 0;
  919. if (odhcpd_valid_hostname(a->hostname))
  920. a->flags &= ~OAF_BROKEN_HOSTNAME;
  921. else
  922. a->flags |= OAF_BROKEN_HOSTNAME;
  923. }
  924. }
  925. if (!(a->flags & OAF_BOUND)) {
  926. a->accept_fr_nonce = accept_fr_nonce;
  927. *incl_fr_opt = accept_fr_nonce;
  928. odhcpd_urandom(a->key, sizeof(a->key));
  929. a->flags |= OAF_BOUND;
  930. } else
  931. *incl_fr_opt = false;
  932. if (!(a->flags & OAF_STATIC))
  933. a->valid_until = ((*leasetime == UINT32_MAX) ? 0 : (time_t)(now + *leasetime));
  934. }
  935. } else if (!assigned && a) {
  936. /* Cleanup failed assignment */
  937. free_dhcpv4_assignment(a);
  938. a = NULL;
  939. }
  940. if (assigned && a)
  941. lease = a;
  942. } else if (msg == DHCPV4_MSG_RELEASE && a) {
  943. a->flags &= ~OAF_BOUND;
  944. if (!(a->flags & OAF_STATIC))
  945. a->valid_until = now - 1;
  946. } else if (msg == DHCPV4_MSG_DECLINE && a) {
  947. a->flags &= ~OAF_BOUND;
  948. if (!(a->flags & OAF_STATIC)) {
  949. memset(a->hwaddr, 0, sizeof(a->hwaddr));
  950. a->valid_until = now + 3600; /* Block address for 1h */
  951. }
  952. }
  953. dhcpv6_write_statefile();
  954. return lease;
  955. }