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