]> git.ipfire.org Git - people/ms/dnsmasq.git/blame - src/lease.c
Add --dnssec-timestamp option and facility.
[people/ms/dnsmasq.git] / src / lease.c
CommitLineData
aff33962 1/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley
9e4abcb5
SK
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
824af85b
SK
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
7
9e4abcb5
SK
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
824af85b 12
73a08a24
SK
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
9e4abcb5
SK
15*/
16
9e4abcb5
SK
17#include "dnsmasq.h"
18
7622fc06
SK
19#ifdef HAVE_DHCP
20
5aabfc78 21static struct dhcp_lease *leases = NULL, *old_leases = NULL;
5e9e0efb 22static int dns_dirty, file_dirty, leases_left;
9e4abcb5 23
5aabfc78 24void lease_init(time_t now)
9e4abcb5 25{
9e4abcb5 26 unsigned long ei;
c72daea8 27 struct all_addr addr;
9e4abcb5 28 struct dhcp_lease *lease;
5aabfc78 29 int clid_len, hw_len, hw_type;
208b65c5 30 FILE *leasestream;
5e9e0efb 31
3be34541 32 leases_left = daemon->dhcp_max;
ceae00dd 33
28866e95 34 if (option_bool(OPT_LEASE_RO))
208b65c5
SK
35 {
36 /* run "<lease_change_script> init" once to get the
37 initial state of the database. If leasefile-ro is
38 set without a script, we just do without any
39 lease database. */
1f15b81d
SK
40#ifdef HAVE_SCRIPT
41 if (daemon->lease_change_command)
208b65c5 42 {
1f15b81d
SK
43 strcpy(daemon->dhcp_buff, daemon->lease_change_command);
44 strcat(daemon->dhcp_buff, " init");
45 leasestream = popen(daemon->dhcp_buff, "r");
208b65c5 46 }
1f15b81d
SK
47 else
48#endif
49 {
50 file_dirty = dns_dirty = 0;
51 return;
52 }
53
208b65c5
SK
54 }
55 else
56 {
57 /* NOTE: need a+ mode to create file if it doesn't exist */
58 leasestream = daemon->lease_stream = fopen(daemon->lease_file, "a+");
59
60 if (!leasestream)
5aabfc78 61 die(_("cannot open or create lease file %s: %s"), daemon->lease_file, EC_FILE);
208b65c5 62
7622fc06 63 /* a+ mode leaves pointer at end. */
208b65c5
SK
64 rewind(leasestream);
65 }
7cebd20f 66
0a852541
SK
67 /* client-id max length is 255 which is 255*2 digits + 254 colons
68 borrow DNS packet buffer which is always larger than 1000 bytes */
208b65c5 69 if (leasestream)
ceae00dd 70 while (fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2) == 2)
208b65c5 71 {
3d7b550f 72#ifdef HAVE_DHCP6
ceae00dd
SK
73 if (strcmp(daemon->dhcp_buff3, "duid") == 0)
74 {
75 daemon->duid_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, 130, NULL, NULL);
76 daemon->duid = safe_malloc(daemon->duid_len);
77 memcpy(daemon->duid, daemon->dhcp_buff2, daemon->duid_len);
78 continue;
79 }
3d7b550f
SK
80#endif
81
ceae00dd
SK
82 ei = atol(daemon->dhcp_buff3);
83
84 if (fscanf(leasestream, " %64s %255s %764s",
85 daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)
86 break;
87
88 clid_len = 0;
89 if (strcmp(daemon->packet, "*") != 0)
90 clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
91
92 if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4) &&
93 (lease = lease4_allocate(addr.addr.addr4)))
94 {
95 hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
96 /* For backwards compatibility, no explict MAC address type means ether. */
97 if (hw_type == 0 && hw_len != 0)
98 hw_type = ARPHRD_ETHER;
99
353ae4d2 100 lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet,
a9ab732e 101 hw_len, hw_type, clid_len, now, 0);
ceae00dd
SK
102
103 if (strcmp(daemon->dhcp_buff, "*") != 0)
104 lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain(lease->addr), NULL);
105 }
c72daea8 106#ifdef HAVE_DHCP6
ceae00dd 107 else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6))
4cb1b320
SK
108 {
109 char *s = daemon->dhcp_buff2;
ceae00dd 110 int lease_type = LEASE_NA;
89500e31 111 int iaid;
ceae00dd 112
4cb1b320
SK
113 if (s[0] == 'T')
114 {
115 lease_type = LEASE_TA;
116 s++;
117 }
4cb1b320 118
89500e31 119 iaid = strtoul(s, NULL, 10);
ceae00dd
SK
120
121 if ((lease = lease6_allocate(&addr.addr.addr6, lease_type)))
122 {
89500e31
SK
123 lease_set_hwaddr(lease, NULL, (unsigned char *)daemon->packet, 0, 0, clid_len, now, 0);
124 lease_set_iaid(lease, iaid);
ceae00dd
SK
125 if (strcmp(daemon->dhcp_buff, "*") != 0)
126 lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain6((struct in6_addr *)lease->hwaddr), NULL);
127 }
4cb1b320 128 }
c72daea8 129#endif
c72daea8 130 else
ceae00dd 131 break;
c72daea8 132
c72daea8 133 if (!lease)
5aabfc78
SK
134 die (_("too many stored leases"), NULL, EC_MISC);
135
5e9e0efb 136#ifdef HAVE_BROKEN_RTC
208b65c5
SK
137 if (ei != 0)
138 lease->expires = (time_t)ei + now;
139 else
140 lease->expires = (time_t)0;
141 lease->length = ei;
5e9e0efb 142#else
208b65c5
SK
143 /* strictly time_t is opaque, but this hack should work on all sane systems,
144 even when sizeof(time_t) == 8 */
145 lease->expires = (time_t)ei;
5e9e0efb 146#endif
208b65c5 147
5aabfc78
SK
148 /* set these correctly: the "old" events are generated later from
149 the startup synthesised SIGHUP. */
ceae00dd 150 lease->flags &= ~(LEASE_NEW | LEASE_CHANGED);
208b65c5
SK
151 }
152
1f15b81d 153#ifdef HAVE_SCRIPT
208b65c5
SK
154 if (!daemon->lease_stream)
155 {
156 int rc = 0;
9e4abcb5 157
208b65c5
SK
158 /* shell returns 127 for "command not found", 126 for bad permissions. */
159 if (!leasestream || (rc = pclose(leasestream)) == -1 || WEXITSTATUS(rc) == 127 || WEXITSTATUS(rc) == 126)
160 {
161 if (WEXITSTATUS(rc) == 127)
162 errno = ENOENT;
163 else if (WEXITSTATUS(rc) == 126)
164 errno = EACCES;
5aabfc78 165 die(_("cannot run lease-init script %s: %s"), daemon->lease_change_command, EC_FILE);
208b65c5
SK
166 }
167
168 if (WEXITSTATUS(rc) != 0)
169 {
170 sprintf(daemon->dhcp_buff, "%d", WEXITSTATUS(rc));
5aabfc78 171 die(_("lease-init script returned exit code %s"), daemon->dhcp_buff, WEXITSTATUS(rc) + EC_INIT_OFFSET);
208b65c5 172 }
9e4abcb5 173 }
1f15b81d 174#endif
7cebd20f
SK
175
176 /* Some leases may have expired */
177 file_dirty = 0;
178 lease_prune(NULL, now);
179 dns_dirty = 1;
44a2a316
SK
180}
181
5aabfc78 182void lease_update_from_configs(void)
44a2a316
SK
183{
184 /* changes to the config may change current leases. */
185
186 struct dhcp_lease *lease;
187 struct dhcp_config *config;
b8187c80 188 char *name;
4cb1b320 189
9e4abcb5 190 for (lease = leases; lease; lease = lease->next)
89500e31
SK
191 if (lease->flags & (LEASE_TA | LEASE_NA))
192 continue;
193 else if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len,
194 lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) &&
195 (config->flags & CONFIG_NAME) &&
196 (!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))
70c5e3e0 197 lease_set_hostname(lease, config->hostname, 1, get_domain(lease->addr), NULL);
5aabfc78 198 else if ((name = host_from_dns(lease->addr)))
70c5e3e0 199 lease_set_hostname(lease, name, 1, get_domain(lease->addr), NULL); /* updates auth flag only */
9e4abcb5 200}
4cb1b320 201
5aabfc78 202static void ourprintf(int *errp, char *format, ...)
9e4abcb5 203{
7cebd20f 204 va_list ap;
5e9e0efb 205
7cebd20f
SK
206 va_start(ap, format);
207 if (!(*errp) && vfprintf(daemon->lease_stream, format, ap) < 0)
208 *errp = errno;
209 va_end(ap);
210}
211
5aabfc78 212void lease_update_file(time_t now)
7cebd20f
SK
213{
214 struct dhcp_lease *lease;
215 time_t next_event;
216 int i, err = 0;
217
208b65c5 218 if (file_dirty != 0 && daemon->lease_stream)
9e4abcb5 219 {
cdeda28f
SK
220 errno = 0;
221 rewind(daemon->lease_stream);
222 if (errno != 0 || ftruncate(fileno(daemon->lease_stream), 0) != 0)
7cebd20f 223 err = errno;
9e4abcb5
SK
224
225 for (lease = leases; lease; lease = lease->next)
226 {
c72daea8
SK
227
228#ifdef HAVE_DHCP6
4cb1b320 229 if (lease->flags & (LEASE_TA | LEASE_NA))
c72daea8
SK
230 continue;
231#endif
232
44a2a316 233#ifdef HAVE_BROKEN_RTC
5aabfc78 234 ourprintf(&err, "%u ", lease->length);
44a2a316 235#else
5aabfc78 236 ourprintf(&err, "%lu ", (unsigned long)lease->expires);
5e9e0efb 237#endif
c72daea8 238
7cebd20f 239 if (lease->hwaddr_type != ARPHRD_ETHER || lease->hwaddr_len == 0)
5aabfc78 240 ourprintf(&err, "%.2x-", lease->hwaddr_type);
5e9e0efb
SK
241 for (i = 0; i < lease->hwaddr_len; i++)
242 {
5aabfc78 243 ourprintf(&err, "%.2x", lease->hwaddr[i]);
7cebd20f 244 if (i != lease->hwaddr_len - 1)
5aabfc78 245 ourprintf(&err, ":");
5e9e0efb 246 }
c72daea8
SK
247
248 inet_ntop(AF_INET, &lease->addr, daemon->addrbuff, ADDRSTRLEN);
5aabfc78 249
c72daea8 250 ourprintf(&err, " %s ", daemon->addrbuff);
1f15b81d
SK
251 ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
252
0a852541 253 if (lease->clid && lease->clid_len != 0)
9e4abcb5
SK
254 {
255 for (i = 0; i < lease->clid_len - 1; i++)
5aabfc78
SK
256 ourprintf(&err, "%.2x:", lease->clid[i]);
257 ourprintf(&err, "%.2x\n", lease->clid[i]);
9e4abcb5
SK
258 }
259 else
5aabfc78 260 ourprintf(&err, "*\n");
9e4abcb5 261 }
7cebd20f 262
c72daea8
SK
263#ifdef HAVE_DHCP6
264 if (daemon->duid)
265 {
266 ourprintf(&err, "duid ");
267 for (i = 0; i < daemon->duid_len - 1; i++)
268 ourprintf(&err, "%.2x:", daemon->duid[i]);
269 ourprintf(&err, "%.2x\n", daemon->duid[i]);
270
271 for (lease = leases; lease; lease = lease->next)
272 {
273
4cb1b320 274 if (!(lease->flags & (LEASE_TA | LEASE_NA)))
c72daea8
SK
275 continue;
276
277#ifdef HAVE_BROKEN_RTC
278 ourprintf(&err, "%u ", lease->length);
279#else
280 ourprintf(&err, "%lu ", (unsigned long)lease->expires);
281#endif
282
89500e31 283 inet_ntop(AF_INET6, &lease->addr6, daemon->addrbuff, ADDRSTRLEN);
c72daea8 284
4cb1b320 285 ourprintf(&err, "%s%u %s ", (lease->flags & LEASE_TA) ? "T" : "",
89500e31 286 lease->iaid, daemon->addrbuff);
c72daea8
SK
287 ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
288
289 if (lease->clid && lease->clid_len != 0)
290 {
291 for (i = 0; i < lease->clid_len - 1; i++)
292 ourprintf(&err, "%.2x:", lease->clid[i]);
293 ourprintf(&err, "%.2x\n", lease->clid[i]);
294 }
295 else
296 ourprintf(&err, "*\n");
297 }
298 }
299#endif
300
7cebd20f
SK
301 if (fflush(daemon->lease_stream) != 0 ||
302 fsync(fileno(daemon->lease_stream)) < 0)
303 err = errno;
304
305 if (!err)
306 file_dirty = 0;
307 }
308
dd0e0a39 309 /* Set alarm for when the first lease expires. */
c5ad4e79
SK
310 next_event = 0;
311
312#ifdef HAVE_DHCP6
353ae4d2 313 /* do timed RAs and determine when the next is, also pings to potential SLAAC addresses */
1f776932 314 if (daemon->doing_ra)
353ae4d2 315 {
919dd7cf 316 time_t event;
353ae4d2 317
919dd7cf
SK
318 if ((event = periodic_slaac(now, leases)) != 0)
319 {
320 if (next_event == 0 || difftime(next_event, event) > 0.0)
321 next_event = event;
322 }
353ae4d2 323
919dd7cf
SK
324 if ((event = periodic_ra(now)) != 0)
325 {
326 if (next_event == 0 || difftime(next_event, event) > 0.0)
327 next_event = event;
328 }
353ae4d2 329 }
c5ad4e79
SK
330#endif
331
332 for (lease = leases; lease; lease = lease->next)
7cebd20f 333 if (lease->expires != 0 &&
dd0e0a39
SK
334 (next_event == 0 || difftime(next_event, lease->expires) > 0.0))
335 next_event = lease->expires;
7cebd20f
SK
336
337 if (err)
338 {
339 if (next_event == 0 || difftime(next_event, LEASE_RETRY + now) > 0.0)
340 next_event = LEASE_RETRY + now;
341
7622fc06 342 my_syslog(MS_DHCP | LOG_ERR, _("failed to write %s: %s (retry in %us)"),
f2621c7f
SK
343 daemon->lease_file, strerror(err),
344 (unsigned int)difftime(next_event, now));
9e4abcb5 345 }
7cebd20f 346
353ae4d2 347 send_alarm(next_event, now);
44a2a316 348}
9e4abcb5 349
801ca9a7 350
3f2873d4 351static int find_interface_v4(struct in_addr local, int if_index, char *label,
801ca9a7 352 struct in_addr netmask, struct in_addr broadcast, void *vparam)
44a2a316
SK
353{
354 struct dhcp_lease *lease;
6d8e8ac0 355 int prefix = netmask_length(netmask);
dc8a1b1b 356
3f2873d4 357 (void) label;
801ca9a7
SK
358 (void) broadcast;
359 (void) vparam;
360
361 for (lease = leases; lease; lease = lease->next)
6d8e8ac0
SK
362 if (!(lease->flags & (LEASE_TA | LEASE_NA)) &&
363 is_same_net(local, lease->addr, netmask) &&
364 prefix > lease->new_prefixlen)
365 {
366 lease->new_interface = if_index;
dc8a1b1b
LPC
367 lease->new_prefixlen = prefix;
368 }
dc8a1b1b 369
801ca9a7
SK
370 return 1;
371}
372
373#ifdef HAVE_DHCP6
374static int find_interface_v6(struct in6_addr *local, int prefix,
bad7b875 375 int scope, int if_index, int flags,
1f776932 376 int preferred, int valid, void *vparam)
801ca9a7
SK
377{
378 struct dhcp_lease *lease;
dc8a1b1b 379
353ae4d2 380 (void)scope;
bad7b875 381 (void)flags;
1f776932
SK
382 (void)preferred;
383 (void)valid;
dc8a1b1b 384 (void)vparam;
801ca9a7
SK
385
386 for (lease = leases; lease; lease = lease->next)
387 if ((lease->flags & (LEASE_TA | LEASE_NA)))
dc8a1b1b
LPC
388 if (is_same_net6(local, &lease->addr6, prefix) && prefix > lease->new_prefixlen) {
389 /* save prefix length for comparison, as we might get shorter matching
390 * prefix in upcoming netlink GETADDR responses
391 * */
392 lease->new_interface = if_index;
393 lease->new_prefixlen = prefix;
394 }
395
801ca9a7
SK
396 return 1;
397}
353ae4d2
SK
398
399void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface)
400{
5ef33279
SK
401 /* We may be doing RA but not DHCPv4, in which case the lease
402 database may not exist and we have nothing to do anyway */
403 if (daemon->dhcp)
404 slaac_ping_reply(sender, packet, interface, leases);
353ae4d2
SK
405}
406
0c050242
SK
407void lease_update_slaac(time_t now)
408{
409 /* Called when we contruct a new RA-names context, to add putative
410 new SLAAC addresses to existing leases. */
411
412 struct dhcp_lease *lease;
413
414 if (daemon->dhcp)
415 for (lease = leases; lease; lease = lease->next)
416 slaac_add_addrs(lease, now, 0);
417}
418
801ca9a7
SK
419#endif
420
421
422/* Find interfaces associated with leases at start-up. This gets updated as
423 we do DHCP transactions, but information about directly-connected subnets
424 is useful from scrips and necessary for determining SLAAC addresses from
425 start-time. */
8b372704 426void lease_find_interfaces(time_t now)
801ca9a7 427{
6d8e8ac0
SK
428 struct dhcp_lease *lease;
429
430 for (lease = leases; lease; lease = lease->next)
431 lease->new_prefixlen = lease->new_interface = 0;
432
353ae4d2
SK
433 iface_enumerate(AF_INET, &now, find_interface_v4);
434#ifdef HAVE_DHCP6
435 iface_enumerate(AF_INET6, &now, find_interface_v6);
3511a928 436#endif
6d8e8ac0
SK
437
438 for (lease = leases; lease; lease = lease->next)
439 if (lease->new_interface != 0)
440 lease_set_interface(lease, lease->new_interface, now);
3511a928 441}
8b372704 442
3511a928
SK
443#ifdef HAVE_DHCP6
444void lease_make_duid(time_t now)
445{
8b372704 446 /* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */
3511a928 447 if (!daemon->duid && daemon->doing_dhcp6)
8b372704
SK
448 {
449 file_dirty = 1;
450 make_duid(now);
451 }
801ca9a7 452}
3511a928
SK
453#endif
454
801ca9a7
SK
455
456
457
353ae4d2 458void lease_update_dns(int force)
801ca9a7
SK
459{
460 struct dhcp_lease *lease;
461
353ae4d2 462 if (daemon->port != 0 && (dns_dirty || force))
9e4abcb5 463 {
8ff55673 464#ifndef HAVE_BROKEN_RTC
e1ff419c
SK
465 /* force transfer to authoritative secondaries */
466 daemon->soa_sn++;
8ff55673 467#endif
e1ff419c 468
801ca9a7
SK
469 cache_unhash_dhcp();
470
9e4abcb5
SK
471 for (lease = leases; lease; lease = lease->next)
472 {
4cb1b320 473 int prot = AF_INET;
801ca9a7 474
4cb1b320
SK
475#ifdef HAVE_DHCP6
476 if (lease->flags & (LEASE_TA | LEASE_NA))
477 prot = AF_INET6;
f444cddb 478 else if (lease->hostname || lease->fqdn)
801ca9a7 479 {
353ae4d2
SK
480 struct slaac_address *slaac;
481
482 for (slaac = lease->slaac_address; slaac; slaac = slaac->next)
483 if (slaac->backoff == 0)
801ca9a7 484 {
801ca9a7 485 if (lease->fqdn)
353ae4d2 486 cache_add_dhcp_entry(lease->fqdn, AF_INET6, (struct all_addr *)&slaac->addr, lease->expires);
801ca9a7 487 if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
353ae4d2 488 cache_add_dhcp_entry(lease->hostname, AF_INET6, (struct all_addr *)&slaac->addr, lease->expires);
801ca9a7
SK
489 }
490 }
4cb1b320 491
9009d746 492 if (lease->fqdn)
4cb1b320 493 cache_add_dhcp_entry(lease->fqdn, prot,
89500e31 494 prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->addr6,
4cb1b320 495 lease->expires);
9009d746 496
28866e95 497 if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
4cb1b320 498 cache_add_dhcp_entry(lease->hostname, prot,
89500e31 499 prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->addr6,
4cb1b320 500 lease->expires);
91543f48
SK
501
502#else
503 if (lease->fqdn)
504 cache_add_dhcp_entry(lease->fqdn, prot, (struct all_addr *)&lease->addr, lease->expires);
505
506 if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
507 cache_add_dhcp_entry(lease->hostname, prot, (struct all_addr *)&lease->addr, lease->expires);
508#endif
9e4abcb5
SK
509 }
510
511 dns_dirty = 0;
512 }
513}
514
515void lease_prune(struct dhcp_lease *target, time_t now)
516{
517 struct dhcp_lease *lease, *tmp, **up;
518
519 for (lease = leases, up = &leases; lease; lease = tmp)
520 {
521 tmp = lease->next;
522 if ((lease->expires != 0 && difftime(now, lease->expires) > 0) || lease == target)
523 {
5e9e0efb 524 file_dirty = 1;
9e4abcb5 525 if (lease->hostname)
7cebd20f
SK
526 dns_dirty = 1;
527
c72daea8 528 *up = lease->next; /* unlink */
7cebd20f
SK
529
530 /* Put on old_leases list 'till we
531 can run the script */
532 lease->next = old_leases;
533 old_leases = lease;
534
44a2a316 535 leases_left++;
9e4abcb5
SK
536 }
537 else
538 up = &lease->next;
539 }
540}
541
542
cdeda28f 543struct dhcp_lease *lease_find_by_client(unsigned char *hwaddr, int hw_len, int hw_type,
0a852541 544 unsigned char *clid, int clid_len)
9e4abcb5 545{
9e4abcb5
SK
546 struct dhcp_lease *lease;
547
0a852541
SK
548 if (clid)
549 for (lease = leases; lease; lease = lease->next)
c72daea8
SK
550 {
551#ifdef HAVE_DHCP6
4cb1b320 552 if (lease->flags & (LEASE_TA | LEASE_NA))
c72daea8
SK
553 continue;
554#endif
555 if (lease->clid && clid_len == lease->clid_len &&
556 memcmp(clid, lease->clid, clid_len) == 0)
557 return lease;
558 }
0a852541
SK
559
560 for (lease = leases; lease; lease = lease->next)
c72daea8
SK
561 {
562#ifdef HAVE_DHCP6
4cb1b320 563 if (lease->flags & (LEASE_TA | LEASE_NA))
c72daea8
SK
564 continue;
565#endif
566 if ((!lease->clid || !clid) &&
567 hw_len != 0 &&
568 lease->hwaddr_len == hw_len &&
569 lease->hwaddr_type == hw_type &&
570 memcmp(hwaddr, lease->hwaddr, hw_len) == 0)
571 return lease;
572 }
573
9e4abcb5
SK
574 return NULL;
575}
576
577struct dhcp_lease *lease_find_by_addr(struct in_addr addr)
578{
579 struct dhcp_lease *lease;
580
581 for (lease = leases; lease; lease = lease->next)
c72daea8
SK
582 {
583#ifdef HAVE_DHCP6
4cb1b320 584 if (lease->flags & (LEASE_TA | LEASE_NA))
c72daea8
SK
585 continue;
586#endif
587 if (lease->addr.s_addr == addr.s_addr)
588 return lease;
589 }
590
9e4abcb5
SK
591 return NULL;
592}
593
52b92f4d 594#ifdef HAVE_DHCP6
a6ebfacf 595/* find address for {CLID, IAID, address} */
4cb1b320
SK
596struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
597 int lease_type, int iaid, struct in6_addr *addr)
52b92f4d
SK
598{
599 struct dhcp_lease *lease;
600
601 for (lease = leases; lease; lease = lease->next)
602 {
89500e31 603 if (!(lease->flags & lease_type) || lease->iaid != iaid)
4cb1b320 604 continue;
52b92f4d 605
89500e31 606 if (!IN6_ARE_ADDR_EQUAL(&lease->addr6, addr))
4cb1b320
SK
607 continue;
608
a6ebfacf 609 if ((clid_len != lease->clid_len ||
4cb1b320
SK
610 memcmp(clid, lease->clid, clid_len) != 0))
611 continue;
612
8b46061e 613 return lease;
52b92f4d
SK
614 }
615
616 return NULL;
617}
618
a6ebfacf
SK
619/* reset "USED flags */
620void lease6_reset(void)
8b46061e
SK
621{
622 struct dhcp_lease *lease;
623
624 for (lease = leases; lease; lease = lease->next)
a6ebfacf
SK
625 lease->flags &= ~LEASE_USED;
626}
627
628/* enumerate all leases belonging to {CLID, IAID} */
629struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_type, unsigned char *clid, int clid_len, int iaid)
630{
631 struct dhcp_lease *lease;
632
633 if (!first)
634 first = leases;
27cb314e
SK
635 else
636 first = first->next;
a6ebfacf
SK
637
638 for (lease = first; lease; lease = lease->next)
8b46061e 639 {
a6ebfacf
SK
640 if (lease->flags & LEASE_USED)
641 continue;
642
89500e31 643 if (!(lease->flags & lease_type) || lease->iaid != iaid)
8b46061e 644 continue;
a6ebfacf
SK
645
646 if ((clid_len != lease->clid_len ||
647 memcmp(clid, lease->clid, clid_len) != 0))
648 continue;
649
650 return lease;
8b46061e 651 }
a6ebfacf
SK
652
653 return NULL;
8b46061e
SK
654}
655
52b92f4d
SK
656struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr)
657{
658 struct dhcp_lease *lease;
4cb1b320 659
52b92f4d
SK
660 for (lease = leases; lease; lease = lease->next)
661 {
4cb1b320 662 if (!(lease->flags & (LEASE_TA | LEASE_NA)))
52b92f4d 663 continue;
4cb1b320 664
89500e31
SK
665 if (is_same_net6(&lease->addr6, net, prefix) &&
666 (prefix == 128 || addr6part(&lease->addr6) == addr))
52b92f4d
SK
667 return lease;
668 }
669
670 return NULL;
0793380b
SK
671}
672
673/* Find largest assigned address in context */
674u64 lease_find_max_addr6(struct dhcp_context *context)
675{
676 struct dhcp_lease *lease;
677 u64 addr = addr6part(&context->start6);
678
679 if (!(context->flags & (CONTEXT_STATIC | CONTEXT_PROXY)))
680 for (lease = leases; lease; lease = lease->next)
681 {
0793380b
SK
682 if (!(lease->flags & (LEASE_TA | LEASE_NA)))
683 continue;
6caacacf 684
89500e31
SK
685 if (is_same_net6(&lease->addr6, &context->start6, 64) &&
686 addr6part(&lease->addr6) > addr6part(&context->start6) &&
687 addr6part(&lease->addr6) <= addr6part(&context->end6) &&
688 addr6part(&lease->addr6) > addr)
689 addr = addr6part(&lease->addr6);
0793380b
SK
690 }
691
692 return addr;
693}
694
52b92f4d
SK
695#endif
696
7de060b0
SK
697/* Find largest assigned address in context */
698struct in_addr lease_find_max_addr(struct dhcp_context *context)
699{
700 struct dhcp_lease *lease;
701 struct in_addr addr = context->start;
702
703 if (!(context->flags & (CONTEXT_STATIC | CONTEXT_PROXY)))
704 for (lease = leases; lease; lease = lease->next)
c72daea8
SK
705 {
706#ifdef HAVE_DHCP6
4cb1b320 707 if (lease->flags & (LEASE_TA | LEASE_NA))
c72daea8
SK
708 continue;
709#endif
710 if (((unsigned)ntohl(lease->addr.s_addr)) > ((unsigned)ntohl(context->start.s_addr)) &&
711 ((unsigned)ntohl(lease->addr.s_addr)) <= ((unsigned)ntohl(context->end.s_addr)) &&
712 ((unsigned)ntohl(lease->addr.s_addr)) > ((unsigned)ntohl(addr.s_addr)))
713 addr = lease->addr;
714 }
7de060b0
SK
715
716 return addr;
717}
9e4abcb5 718
c72daea8 719static struct dhcp_lease *lease_allocate(void)
9e4abcb5
SK
720{
721 struct dhcp_lease *lease;
5aabfc78 722 if (!leases_left || !(lease = whine_malloc(sizeof(struct dhcp_lease))))
9e4abcb5
SK
723 return NULL;
724
7cebd20f 725 memset(lease, 0, sizeof(struct dhcp_lease));
4cb1b320 726 lease->flags = LEASE_NEW;
9e4abcb5 727 lease->expires = 1;
5e9e0efb
SK
728#ifdef HAVE_BROKEN_RTC
729 lease->length = 0xffffffff; /* illegal value */
730#endif
89500e31 731 lease->hwaddr_len = 256; /* illegal value */
9e4abcb5
SK
732 lease->next = leases;
733 leases = lease;
734
5e9e0efb 735 file_dirty = 1;
44a2a316 736 leases_left--;
9e4abcb5
SK
737
738 return lease;
739}
740
52b92f4d 741struct dhcp_lease *lease4_allocate(struct in_addr addr)
c72daea8
SK
742{
743 struct dhcp_lease *lease = lease_allocate();
0b0a73c1 744 if (lease)
89500e31
SK
745 lease->addr = addr;
746
c72daea8
SK
747 return lease;
748}
749
750#ifdef HAVE_DHCP6
4cb1b320 751struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type)
c72daea8
SK
752{
753 struct dhcp_lease *lease = lease_allocate();
0b0a73c1
SK
754
755 if (lease)
756 {
89500e31 757 lease->addr6 = *addrp;
0b0a73c1 758 lease->flags |= lease_type;
89500e31 759 lease->iaid = 0;
0b0a73c1 760 }
c72daea8
SK
761
762 return lease;
763}
764#endif
765
5e9e0efb 766void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now)
9e4abcb5 767{
dd0e0a39
SK
768 time_t exp;
769
5e9e0efb
SK
770 if (len == 0xffffffff)
771 {
772 exp = 0;
773 len = 0;
774 }
dd0e0a39
SK
775 else
776 {
777 exp = now + (time_t)len;
778 /* Check for 2038 overflow. Make the lease
779 inifinite in that case, as the least disruptive
780 thing we can do. */
781 if (difftime(exp, now) <= 0.0)
782 exp = 0;
783 }
784
9e4abcb5 785 if (exp != lease->expires)
0a852541 786 {
0a852541 787 dns_dirty = 1;
5e9e0efb
SK
788 lease->expires = exp;
789#ifndef HAVE_BROKEN_RTC
4cb1b320
SK
790 lease->flags |= LEASE_AUX_CHANGED;
791 file_dirty = 1;
5e9e0efb 792#endif
0a852541 793 }
5e9e0efb
SK
794
795#ifdef HAVE_BROKEN_RTC
796 if (len != lease->length)
797 {
798 lease->length = len;
b7f40201
SK
799 lease->flags |= LEASE_AUX_CHANGED;
800 file_dirty = 1;
5e9e0efb
SK
801 }
802#endif
803}
9e4abcb5 804
89500e31
SK
805#ifdef HAVE_DHCP6
806void lease_set_iaid(struct dhcp_lease *lease, int iaid)
807{
808 if (lease->iaid != iaid)
809 {
810 lease->iaid = iaid;
811 lease->flags |= LEASE_CHANGED;
812 }
813}
814#endif
815
7cebd20f 816void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
a9ab732e
SK
817 unsigned char *clid, int hw_len, int hw_type, int clid_len,
818 time_t now, int force)
9e4abcb5 819{
353ae4d2 820#ifdef HAVE_DHCP6
a9ab732e 821 int change = force;
353ae4d2
SK
822 lease->flags |= LEASE_HAVE_HWADDR;
823#endif
824
a9ab732e 825 (void)force;
408c368f 826 (void)now;
a9ab732e 827
cdeda28f
SK
828 if (hw_len != lease->hwaddr_len ||
829 hw_type != lease->hwaddr_type ||
7cebd20f 830 (hw_len != 0 && memcmp(lease->hwaddr, hwaddr, hw_len) != 0))
9e4abcb5 831 {
4cb1b320
SK
832 if (hw_len != 0)
833 memcpy(lease->hwaddr, hwaddr, hw_len);
cdeda28f
SK
834 lease->hwaddr_len = hw_len;
835 lease->hwaddr_type = hw_type;
4cb1b320
SK
836 lease->flags |= LEASE_CHANGED;
837 file_dirty = 1; /* run script on change */
9e4abcb5 838 }
0a852541
SK
839
840 /* only update clid when one is available, stops packets
841 without a clid removing the record. Lease init uses
842 clid_len == 0 for no clid. */
843 if (clid_len != 0 && clid)
844 {
845 if (!lease->clid)
846 lease->clid_len = 0;
847
848 if (lease->clid_len != clid_len)
849 {
4cb1b320
SK
850 lease->flags |= LEASE_AUX_CHANGED;
851 file_dirty = 1;
5aabfc78
SK
852 free(lease->clid);
853 if (!(lease->clid = whine_malloc(clid_len)))
7cebd20f 854 return;
353ae4d2
SK
855#ifdef HAVE_DHCP6
856 change = 1;
857#endif
0a852541
SK
858 }
859 else if (memcmp(lease->clid, clid, clid_len) != 0)
4cb1b320
SK
860 {
861 lease->flags |= LEASE_AUX_CHANGED;
862 file_dirty = 1;
353ae4d2
SK
863#ifdef HAVE_DHCP6
864 change = 1;
865#endif
4cb1b320 866 }
353ae4d2 867
0a852541
SK
868 lease->clid_len = clid_len;
869 memcpy(lease->clid, clid, clid_len);
870 }
353ae4d2
SK
871
872#ifdef HAVE_DHCP6
873 if (change)
a9ab732e 874 slaac_add_addrs(lease, now, force);
353ae4d2 875#endif
9e4abcb5
SK
876}
877
9009d746
SK
878static void kill_name(struct dhcp_lease *lease)
879{
880 /* run script to say we lost our old name */
881
882 /* this shouldn't happen unless updates are very quick and the
883 script very slow, we just avoid a memory leak if it does. */
884 free(lease->old_hostname);
885
886 /* If we know the fqdn, pass that. The helper will derive the
4cb1b320 887 unqualified name from it, free the unqualified name here. */
9009d746
SK
888
889 if (lease->fqdn)
890 {
891 lease->old_hostname = lease->fqdn;
892 free(lease->hostname);
893 }
894 else
895 lease->old_hostname = lease->hostname;
896
897 lease->hostname = lease->fqdn = NULL;
898}
899
70c5e3e0 900void lease_set_hostname(struct dhcp_lease *lease, char *name, int auth, char *domain, char *config_domain)
9e4abcb5
SK
901{
902 struct dhcp_lease *lease_tmp;
903 char *new_name = NULL, *new_fqdn = NULL;
70c5e3e0
SK
904
905 if (config_domain && (!domain || !hostname_isequal(domain, config_domain)))
906 my_syslog(MS_DHCP | LOG_WARNING, _("Ignoring domain %s for DHCP host name %s"), config_domain, name);
9009d746 907
a222641c 908 if (lease->hostname && name && hostname_isequal(lease->hostname, name))
b8187c80 909 {
4cb1b320
SK
910 if (auth)
911 lease->flags |= LEASE_AUTH_NAME;
b8187c80
SK
912 return;
913 }
7cebd20f 914
9e4abcb5
SK
915 if (!name && !lease->hostname)
916 return;
917
918 /* If a machine turns up on a new net without dropping the old lease,
919 or two machines claim the same name, then we end up with two interfaces with
b8187c80 920 the same name. Check for that here and remove the name from the old lease.
4cb1b320
SK
921 Note that IPv6 leases are different. All the leases to the same DUID are
922 allowed the same name.
923
b8187c80 924 Don't allow a name from the client to override a name from dnsmasq config. */
9e4abcb5
SK
925
926 if (name)
927 {
9009d746
SK
928 if ((new_name = whine_malloc(strlen(name) + 1)))
929 {
9009d746 930 strcpy(new_name, name);
4cb1b320 931 if (domain && (new_fqdn = whine_malloc(strlen(new_name) + strlen(domain) + 2)))
9009d746
SK
932 {
933 strcpy(new_fqdn, name);
934 strcat(new_fqdn, ".");
4cb1b320 935 strcat(new_fqdn, domain);
9009d746
SK
936 }
937 }
938
939 /* Depending on mode, we check either unqualified name or FQDN. */
9e4abcb5 940 for (lease_tmp = leases; lease_tmp; lease_tmp = lease_tmp->next)
9e4abcb5 941 {
28866e95 942 if (option_bool(OPT_DHCP_FQDN))
9009d746 943 {
4cb1b320 944 if (!new_fqdn || !lease_tmp->fqdn || !hostname_isequal(lease_tmp->fqdn, new_fqdn))
9009d746
SK
945 continue;
946 }
947 else
948 {
949 if (!new_name || !lease_tmp->hostname || !hostname_isequal(lease_tmp->hostname, new_name) )
950 continue;
951 }
4cb1b320
SK
952
953 if (lease->flags & (LEASE_TA | LEASE_NA))
954 {
955 if (!(lease_tmp->flags & (LEASE_TA | LEASE_NA)))
956 continue;
957
ceae00dd 958 /* another lease for the same DUID is OK for IPv6 */
4cb1b320
SK
959 if (lease->clid_len == lease_tmp->clid_len &&
960 lease->clid && lease_tmp->clid &&
961 memcmp(lease->clid, lease_tmp->clid, lease->clid_len) == 0)
962 continue;
963 }
964 else if (lease_tmp->flags & (LEASE_TA | LEASE_NA))
965 continue;
966
967 if ((lease_tmp->flags & LEASE_AUTH_NAME) && !auth)
9009d746
SK
968 {
969 free(new_name);
970 free(new_fqdn);
971 return;
972 }
973
974 kill_name(lease_tmp);
975 break;
9e4abcb5
SK
976 }
977 }
978
979 if (lease->hostname)
9009d746 980 kill_name(lease);
1697269c 981
9e4abcb5
SK
982 lease->hostname = new_name;
983 lease->fqdn = new_fqdn;
4cb1b320
SK
984
985 if (auth)
986 lease->flags |= LEASE_AUTH_NAME;
9e4abcb5 987
5e9e0efb 988 file_dirty = 1;
7cebd20f 989 dns_dirty = 1;
4cb1b320 990 lease->flags |= LEASE_CHANGED; /* run script on change */
7cebd20f
SK
991}
992
353ae4d2 993void lease_set_interface(struct dhcp_lease *lease, int interface, time_t now)
824af85b 994{
408c368f
VG
995 (void)now;
996
824af85b
SK
997 if (lease->last_interface == interface)
998 return;
999
1000 lease->last_interface = interface;
4cb1b320 1001 lease->flags |= LEASE_CHANGED;
353ae4d2
SK
1002
1003#ifdef HAVE_DHCP6
a9ab732e 1004 slaac_add_addrs(lease, now, 0);
353ae4d2 1005#endif
824af85b
SK
1006}
1007
5aabfc78
SK
1008void rerun_scripts(void)
1009{
1010 struct dhcp_lease *lease;
1011
1012 for (lease = leases; lease; lease = lease->next)
4cb1b320 1013 lease->flags |= LEASE_CHANGED;
5aabfc78
SK
1014}
1015
7cebd20f
SK
1016/* deleted leases get transferred to the old_leases list.
1017 remove them here, after calling the lease change
1697269c
SK
1018 script. Also run the lease change script on new/modified leases.
1019
1020 Return zero if nothing to do. */
5aabfc78 1021int do_script_run(time_t now)
7cebd20f
SK
1022{
1023 struct dhcp_lease *lease;
9e4abcb5 1024
408c368f
VG
1025 (void)now;
1026
9009d746
SK
1027#ifdef HAVE_DBUS
1028 /* If we're going to be sending DBus signals, but the connection is not yet up,
1029 delay everything until it is. */
28866e95 1030 if (option_bool(OPT_DBUS) && !daemon->dbus)
9009d746
SK
1031 return 0;
1032#endif
1033
1697269c 1034 if (old_leases)
7cebd20f 1035 {
7cebd20f 1036 lease = old_leases;
1697269c
SK
1037
1038 /* If the lease still has an old_hostname, do the "old" action on that first */
1039 if (lease->old_hostname)
1040 {
1f15b81d 1041#ifdef HAVE_SCRIPT
5aabfc78
SK
1042 queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
1043#endif
1697269c
SK
1044 free(lease->old_hostname);
1045 lease->old_hostname = NULL;
1046 return 1;
1047 }
1048 else
1049 {
353ae4d2
SK
1050#ifdef HAVE_DHCP6
1051 struct slaac_address *slaac, *tmp;
1052 for (slaac = lease->slaac_address; slaac; slaac = tmp)
1053 {
1054 tmp = slaac->next;
1055 free(slaac);
1056 }
1057#endif
9009d746 1058 kill_name(lease);
1f15b81d 1059#ifdef HAVE_SCRIPT
9009d746 1060 queue_script(ACTION_DEL, lease, lease->old_hostname, now);
1f15b81d
SK
1061#endif
1062#ifdef HAVE_DBUS
1063 emit_dbus_signal(ACTION_DEL, lease, lease->old_hostname);
5aabfc78 1064#endif
1697269c
SK
1065 old_leases = lease->next;
1066
9009d746 1067 free(lease->old_hostname);
5aabfc78 1068 free(lease->clid);
316e2730 1069 free(lease->extradata);
1697269c
SK
1070 free(lease);
1071
1072 return 1;
1073 }
7cebd20f 1074 }
1697269c
SK
1075
1076 /* make sure we announce the loss of a hostname before its new location. */
1077 for (lease = leases; lease; lease = lease->next)
1078 if (lease->old_hostname)
1079 {
1f15b81d 1080#ifdef HAVE_SCRIPT
5aabfc78
SK
1081 queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
1082#endif
1697269c
SK
1083 free(lease->old_hostname);
1084 lease->old_hostname = NULL;
1085 return 1;
1086 }
1087
7cebd20f 1088 for (lease = leases; lease; lease = lease->next)
4cb1b320
SK
1089 if ((lease->flags & (LEASE_NEW | LEASE_CHANGED)) ||
1090 ((lease->flags & LEASE_AUX_CHANGED) && option_bool(OPT_LEASE_RO)))
7cebd20f 1091 {
1f15b81d 1092#ifdef HAVE_SCRIPT
4cb1b320 1093 queue_script((lease->flags & LEASE_NEW) ? ACTION_ADD : ACTION_OLD, lease,
9009d746 1094 lease->fqdn ? lease->fqdn : lease->hostname, now);
1f15b81d
SK
1095#endif
1096#ifdef HAVE_DBUS
4cb1b320 1097 emit_dbus_signal((lease->flags & LEASE_NEW) ? ACTION_ADD : ACTION_OLD, lease,
1f15b81d 1098 lease->fqdn ? lease->fqdn : lease->hostname);
5aabfc78 1099#endif
4cb1b320 1100 lease->flags &= ~(LEASE_NEW | LEASE_CHANGED | LEASE_AUX_CHANGED);
1697269c 1101
316e2730
SK
1102 /* this is used for the "add" call, then junked, since they're not in the database */
1103 free(lease->extradata);
1104 lease->extradata = NULL;
1697269c
SK
1105
1106 return 1;
7cebd20f 1107 }
1697269c
SK
1108
1109 return 0; /* nothing to do */
7cebd20f 1110}
7622fc06 1111
ceae00dd
SK
1112#ifdef HAVE_SCRIPT
1113void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, unsigned int len, int delim)
1114{
1115 unsigned int i;
1116
1117 /* check for embeded NULLs */
1118 for (i = 0; i < len; i++)
1119 if (data[i] == 0)
1120 {
1121 len = i;
1122 break;
1123 }
1124
1125 if ((lease->extradata_size - lease->extradata_len) < (len + 1))
1126 {
1127 size_t newsz = lease->extradata_len + len + 100;
1128 unsigned char *new = whine_malloc(newsz);
1129
1130 if (!new)
1131 return;
1132
1133 if (lease->extradata)
1134 {
1135 memcpy(new, lease->extradata, lease->extradata_len);
1136 free(lease->extradata);
1137 }
1138
1139 lease->extradata = new;
1140 lease->extradata_size = newsz;
1141 }
1142
1143 if (len != 0)
1144 memcpy(lease->extradata + lease->extradata_len, data, len);
1145 lease->extradata[lease->extradata_len + len] = delim;
1146 lease->extradata_len += len + 1;
1147}
1148#endif
1149
7622fc06 1150#endif
7cebd20f
SK
1151
1152
1153
9e4abcb5 1154