1 /* dnsmasq is Copyright (c) 2000-2013 Simon Kelley
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
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
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.
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/>.
21 static struct dhcp_lease
*leases
= NULL
, *old_leases
= NULL
;
22 static int dns_dirty
, file_dirty
, leases_left
;
24 void lease_init(time_t now
)
28 struct dhcp_lease
*lease
;
29 int clid_len
, hw_len
, hw_type
;
32 leases_left
= daemon
->dhcp_max
;
34 if (option_bool(OPT_LEASE_RO
))
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
41 if (daemon
->lease_change_command
)
43 strcpy(daemon
->dhcp_buff
, daemon
->lease_change_command
);
44 strcat(daemon
->dhcp_buff
, " init");
45 leasestream
= popen(daemon
->dhcp_buff
, "r");
50 file_dirty
= dns_dirty
= 0;
57 /* NOTE: need a+ mode to create file if it doesn't exist */
58 leasestream
= daemon
->lease_stream
= fopen(daemon
->lease_file
, "a+");
61 die(_("cannot open or create lease file %s: %s"), daemon
->lease_file
, EC_FILE
);
63 /* a+ mode leaves pointer at end. */
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 */
70 while (fscanf(leasestream
, "%255s %255s", daemon
->dhcp_buff3
, daemon
->dhcp_buff2
) == 2)
73 if (strcmp(daemon
->dhcp_buff3
, "duid") == 0)
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
);
82 ei
= atol(daemon
->dhcp_buff3
);
84 if (fscanf(leasestream
, " %64s %255s %764s",
85 daemon
->namebuff
, daemon
->dhcp_buff
, daemon
->packet
) != 3)
89 if (strcmp(daemon
->packet
, "*") != 0)
90 clid_len
= parse_hex(daemon
->packet
, (unsigned char *)daemon
->packet
, 255, NULL
, NULL
);
92 if (inet_pton(AF_INET
, daemon
->namebuff
, &addr
.addr
.addr4
) &&
93 (lease
= lease4_allocate(addr
.addr
.addr4
)))
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
;
100 lease_set_hwaddr(lease
, (unsigned char *)daemon
->dhcp_buff2
, (unsigned char *)daemon
->packet
,
101 hw_len
, hw_type
, clid_len
, now
, 0);
103 if (strcmp(daemon
->dhcp_buff
, "*") != 0)
104 lease_set_hostname(lease
, daemon
->dhcp_buff
, 0, get_domain(lease
->addr
), NULL
);
107 else if (inet_pton(AF_INET6
, daemon
->namebuff
, &addr
.addr
.addr6
))
109 char *s
= daemon
->dhcp_buff2
;
110 int lease_type
= LEASE_NA
;
114 lease_type
= LEASE_TA
;
120 if ((lease
= lease6_allocate(&addr
.addr
.addr6
, lease_type
)))
122 lease_set_hwaddr(lease
, NULL
, (unsigned char *)daemon
->packet
, 0, hw_type
, clid_len
, now
, 0);
124 if (strcmp(daemon
->dhcp_buff
, "*") != 0)
125 lease_set_hostname(lease
, daemon
->dhcp_buff
, 0, get_domain6((struct in6_addr
*)lease
->hwaddr
), NULL
);
133 die (_("too many stored leases"), NULL
, EC_MISC
);
135 #ifdef HAVE_BROKEN_RTC
137 lease
->expires
= (time_t)ei
+ now
;
139 lease
->expires
= (time_t)0;
142 /* strictly time_t is opaque, but this hack should work on all sane systems,
143 even when sizeof(time_t) == 8 */
144 lease
->expires
= (time_t)ei
;
147 /* set these correctly: the "old" events are generated later from
148 the startup synthesised SIGHUP. */
149 lease
->flags
&= ~(LEASE_NEW
| LEASE_CHANGED
);
153 if (!daemon
->lease_stream
)
157 /* shell returns 127 for "command not found", 126 for bad permissions. */
158 if (!leasestream
|| (rc
= pclose(leasestream
)) == -1 || WEXITSTATUS(rc
) == 127 || WEXITSTATUS(rc
) == 126)
160 if (WEXITSTATUS(rc
) == 127)
162 else if (WEXITSTATUS(rc
) == 126)
164 die(_("cannot run lease-init script %s: %s"), daemon
->lease_change_command
, EC_FILE
);
167 if (WEXITSTATUS(rc
) != 0)
169 sprintf(daemon
->dhcp_buff
, "%d", WEXITSTATUS(rc
));
170 die(_("lease-init script returned exit code %s"), daemon
->dhcp_buff
, WEXITSTATUS(rc
) + EC_INIT_OFFSET
);
175 /* Some leases may have expired */
177 lease_prune(NULL
, now
);
181 void lease_update_from_configs(void)
183 /* changes to the config may change current leases. */
185 struct dhcp_lease
*lease
;
186 struct dhcp_config
*config
;
189 for (lease
= leases
; lease
; lease
= lease
->next
)
190 if ((config
= find_config(daemon
->dhcp_conf
, NULL
, lease
->clid
, lease
->clid_len
,
191 lease
->hwaddr
, lease
->hwaddr_len
, lease
->hwaddr_type
, NULL
)) &&
192 (config
->flags
& CONFIG_NAME
) &&
193 (!(config
->flags
& CONFIG_ADDR
) || config
->addr
.s_addr
== lease
->addr
.s_addr
))
194 lease_set_hostname(lease
, config
->hostname
, 1, get_domain(lease
->addr
), NULL
);
195 else if ((name
= host_from_dns(lease
->addr
)))
196 lease_set_hostname(lease
, name
, 1, get_domain(lease
->addr
), NULL
); /* updates auth flag only */
199 static void ourprintf(int *errp
, char *format
, ...)
203 va_start(ap
, format
);
204 if (!(*errp
) && vfprintf(daemon
->lease_stream
, format
, ap
) < 0)
209 void lease_update_file(time_t now
)
211 struct dhcp_lease
*lease
;
215 if (file_dirty
!= 0 && daemon
->lease_stream
)
218 rewind(daemon
->lease_stream
);
219 if (errno
!= 0 || ftruncate(fileno(daemon
->lease_stream
), 0) != 0)
222 for (lease
= leases
; lease
; lease
= lease
->next
)
226 if (lease
->flags
& (LEASE_TA
| LEASE_NA
))
231 ourprintf(&err
, "%lu ", (unsigned long)lease
->expires
- now
);
233 #ifdef HAVE_BROKEN_RTC
234 ourprintf(&err
, "%u ", lease
->length
);
236 ourprintf(&err
, "%lu ", (unsigned long)lease
->expires
);
240 if (lease
->hwaddr_type
!= ARPHRD_ETHER
|| lease
->hwaddr_len
== 0)
241 ourprintf(&err
, "%.2x-", lease
->hwaddr_type
);
242 for (i
= 0; i
< lease
->hwaddr_len
; i
++)
244 ourprintf(&err
, "%.2x", lease
->hwaddr
[i
]);
245 if (i
!= lease
->hwaddr_len
- 1)
246 ourprintf(&err
, ":");
249 inet_ntop(AF_INET
, &lease
->addr
, daemon
->addrbuff
, ADDRSTRLEN
);
251 ourprintf(&err
, " %s ", daemon
->addrbuff
);
252 ourprintf(&err
, "%s ", lease
->hostname
? lease
->hostname
: "*");
254 if (lease
->clid
&& lease
->clid_len
!= 0)
256 for (i
= 0; i
< lease
->clid_len
- 1; i
++)
257 ourprintf(&err
, "%.2x:", lease
->clid
[i
]);
258 ourprintf(&err
, "%.2x\n", lease
->clid
[i
]);
261 ourprintf(&err
, "*\n");
267 ourprintf(&err
, "duid ");
268 for (i
= 0; i
< daemon
->duid_len
- 1; i
++)
269 ourprintf(&err
, "%.2x:", daemon
->duid
[i
]);
270 ourprintf(&err
, "%.2x\n", daemon
->duid
[i
]);
272 for (lease
= leases
; lease
; lease
= lease
->next
)
275 if (!(lease
->flags
& (LEASE_TA
| LEASE_NA
)))
278 #ifdef HAVE_BROKEN_RTC
279 ourprintf(&err
, "%u ", lease
->length
);
281 ourprintf(&err
, "%lu ", (unsigned long)lease
->expires
);
284 inet_ntop(AF_INET6
, lease
->hwaddr
, daemon
->addrbuff
, ADDRSTRLEN
);
286 ourprintf(&err
, "%s%u %s ", (lease
->flags
& LEASE_TA
) ? "T" : "",
287 lease
->hwaddr_type
, daemon
->addrbuff
);
288 ourprintf(&err
, "%s ", lease
->hostname
? lease
->hostname
: "*");
290 if (lease
->clid
&& lease
->clid_len
!= 0)
292 for (i
= 0; i
< lease
->clid_len
- 1; i
++)
293 ourprintf(&err
, "%.2x:", lease
->clid
[i
]);
294 ourprintf(&err
, "%.2x\n", lease
->clid
[i
]);
297 ourprintf(&err
, "*\n");
302 if (fflush(daemon
->lease_stream
) != 0 ||
303 fsync(fileno(daemon
->lease_stream
)) < 0)
310 /* Set alarm for when the first lease expires + slop. */
314 /* do timed RAs and determine when the next is, also pings to potential SLAAC addresses */
315 if (daemon
->doing_ra
)
319 if ((event
= periodic_slaac(now
, leases
)) != 0)
321 if (next_event
== 0 || difftime(next_event
, event
) > 0.0)
325 if ((event
= periodic_ra(now
)) != 0)
327 if (next_event
== 0 || difftime(next_event
, event
) > 0.0)
333 for (lease
= leases
; lease
; lease
= lease
->next
)
334 if (lease
->expires
!= 0 &&
335 (next_event
== 0 || difftime(next_event
, lease
->expires
+ 10) > 0.0))
336 next_event
= lease
->expires
+ 10;
340 if (next_event
== 0 || difftime(next_event
, LEASE_RETRY
+ now
) > 0.0)
341 next_event
= LEASE_RETRY
+ now
;
343 my_syslog(MS_DHCP
| LOG_ERR
, _("failed to write %s: %s (retry in %us)"),
344 daemon
->lease_file
, strerror(err
),
345 (unsigned int)difftime(next_event
, now
));
348 send_alarm(next_event
, now
);
352 static int find_interface_v4(struct in_addr local
, int if_index
,
353 struct in_addr netmask
, struct in_addr broadcast
, void *vparam
)
355 struct dhcp_lease
*lease
;
360 for (lease
= leases
; lease
; lease
= lease
->next
)
361 if (!(lease
->flags
& (LEASE_TA
| LEASE_NA
)))
362 if (is_same_net(local
, lease
->addr
, netmask
))
363 lease_set_interface(lease
, if_index
, *((time_t *)vparam
));
369 static int find_interface_v6(struct in6_addr
*local
, int prefix
,
370 int scope
, int if_index
, int flags
,
371 int preferred
, int valid
, void *vparam
)
373 struct dhcp_lease
*lease
;
380 for (lease
= leases
; lease
; lease
= lease
->next
)
381 if ((lease
->flags
& (LEASE_TA
| LEASE_NA
)))
382 if (is_same_net6(local
, (struct in6_addr
*)&lease
->hwaddr
, prefix
))
383 lease_set_interface(lease
, if_index
, *((time_t *)vparam
));
388 void lease_ping_reply(struct in6_addr
*sender
, unsigned char *packet
, char *interface
)
390 /* We may be doing RA but not DHCPv4, in which case the lease
391 database may not exist and we have nothing to do anyway */
393 slaac_ping_reply(sender
, packet
, interface
, leases
);
396 void lease_update_slaac(time_t now
)
398 /* Called when we contruct a new RA-names context, to add putative
399 new SLAAC addresses to existing leases. */
401 struct dhcp_lease
*lease
;
404 for (lease
= leases
; lease
; lease
= lease
->next
)
405 slaac_add_addrs(lease
, now
, 0);
411 /* Find interfaces associated with leases at start-up. This gets updated as
412 we do DHCP transactions, but information about directly-connected subnets
413 is useful from scrips and necessary for determining SLAAC addresses from
415 void lease_find_interfaces(time_t now
)
417 iface_enumerate(AF_INET
, &now
, find_interface_v4
);
419 iface_enumerate(AF_INET6
, &now
, find_interface_v6
);
421 /* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */
422 if (!daemon
->duid
&& daemon
->dhcp6
)
432 void lease_update_dns(int force
)
434 struct dhcp_lease
*lease
;
436 if (daemon
->port
!= 0 && (dns_dirty
|| force
))
438 #ifndef HAVE_BROKEN_RTC
439 /* force transfer to authoritative secondaries */
445 for (lease
= leases
; lease
; lease
= lease
->next
)
450 if (lease
->flags
& (LEASE_TA
| LEASE_NA
))
452 else if (lease
->hostname
|| lease
->fqdn
)
454 struct slaac_address
*slaac
;
456 for (slaac
= lease
->slaac_address
; slaac
; slaac
= slaac
->next
)
457 if (slaac
->backoff
== 0)
460 cache_add_dhcp_entry(lease
->fqdn
, AF_INET6
, (struct all_addr
*)&slaac
->addr
, lease
->expires
);
461 if (!option_bool(OPT_DHCP_FQDN
) && lease
->hostname
)
462 cache_add_dhcp_entry(lease
->hostname
, AF_INET6
, (struct all_addr
*)&slaac
->addr
, lease
->expires
);
468 cache_add_dhcp_entry(lease
->fqdn
, prot
,
469 prot
== AF_INET
? (struct all_addr
*)&lease
->addr
: (struct all_addr
*)&lease
->hwaddr
,
472 if (!option_bool(OPT_DHCP_FQDN
) && lease
->hostname
)
473 cache_add_dhcp_entry(lease
->hostname
, prot
,
474 prot
== AF_INET
? (struct all_addr
*)&lease
->addr
: (struct all_addr
*)&lease
->hwaddr
,
482 void lease_prune(struct dhcp_lease
*target
, time_t now
)
484 struct dhcp_lease
*lease
, *tmp
, **up
;
486 for (lease
= leases
, up
= &leases
; lease
; lease
= tmp
)
489 if ((lease
->expires
!= 0 && difftime(now
, lease
->expires
) > 0) || lease
== target
)
495 *up
= lease
->next
; /* unlink */
497 /* Put on old_leases list 'till we
498 can run the script */
499 lease
->next
= old_leases
;
510 struct dhcp_lease
*lease_find_by_client(unsigned char *hwaddr
, int hw_len
, int hw_type
,
511 unsigned char *clid
, int clid_len
)
513 struct dhcp_lease
*lease
;
516 for (lease
= leases
; lease
; lease
= lease
->next
)
519 if (lease
->flags
& (LEASE_TA
| LEASE_NA
))
522 if (lease
->clid
&& clid_len
== lease
->clid_len
&&
523 memcmp(clid
, lease
->clid
, clid_len
) == 0)
527 for (lease
= leases
; lease
; lease
= lease
->next
)
530 if (lease
->flags
& (LEASE_TA
| LEASE_NA
))
533 if ((!lease
->clid
|| !clid
) &&
535 lease
->hwaddr_len
== hw_len
&&
536 lease
->hwaddr_type
== hw_type
&&
537 memcmp(hwaddr
, lease
->hwaddr
, hw_len
) == 0)
544 struct dhcp_lease
*lease_find_by_addr(struct in_addr addr
)
546 struct dhcp_lease
*lease
;
548 for (lease
= leases
; lease
; lease
= lease
->next
)
551 if (lease
->flags
& (LEASE_TA
| LEASE_NA
))
554 if (lease
->addr
.s_addr
== addr
.s_addr
)
562 /* addr or clid may be NULL for "don't care, both NULL resets "USED" flags both
563 set activates USED check */
564 struct dhcp_lease
*lease6_find(unsigned char *clid
, int clid_len
,
565 int lease_type
, int iaid
, struct in6_addr
*addr
)
567 struct dhcp_lease
*lease
;
569 for (lease
= leases
; lease
; lease
= lease
->next
)
571 if (!(lease
->flags
& lease_type
) || lease
->hwaddr_type
!= iaid
)
574 if (clid
&& addr
&& (lease
->flags
& LEASE_USED
))
577 if (addr
&& memcmp(lease
->hwaddr
, addr
, IN6ADDRSZ
) != 0)
581 (clid_len
!= lease
->clid_len
||
582 memcmp(clid
, lease
->clid
, clid_len
) != 0))
585 lease
->flags
|= LEASE_USED
;
592 void lease6_filter(int lease_type
, int iaid
, struct dhcp_context
*context
)
594 struct dhcp_lease
*lease
;
596 for (lease
= leases
; lease
; lease
= lease
->next
)
598 /* reset "USED flag */
599 lease
->flags
&= ~LEASE_USED
;
601 if (!(lease
->flags
& lease_type
) || lease
->hwaddr_type
!= iaid
)
604 /* leases on the wrong interface get filtered out here */
605 if (!is_addr_in_context6(context
, (struct in6_addr
*)&lease
->hwaddr
))
606 lease
->flags
|= LEASE_USED
;
610 struct dhcp_lease
*lease6_find_by_addr(struct in6_addr
*net
, int prefix
, u64 addr
)
612 struct dhcp_lease
*lease
;
614 for (lease
= leases
; lease
; lease
= lease
->next
)
616 if (!(lease
->flags
& (LEASE_TA
| LEASE_NA
)))
619 if (is_same_net6((struct in6_addr
*)lease
->hwaddr
, net
, prefix
) &&
620 (prefix
== 128 || addr6part((struct in6_addr
*)lease
->hwaddr
) == addr
))
627 /* Find largest assigned address in context */
628 u64
lease_find_max_addr6(struct dhcp_context
*context
)
630 struct dhcp_lease
*lease
;
631 u64 addr
= addr6part(&context
->start6
);
633 if (!(context
->flags
& (CONTEXT_STATIC
| CONTEXT_PROXY
)))
634 for (lease
= leases
; lease
; lease
= lease
->next
)
636 if (!(lease
->flags
& (LEASE_TA
| LEASE_NA
)))
639 if (is_same_net6((struct in6_addr
*)lease
->hwaddr
, &context
->start6
, 64) &&
640 addr6part((struct in6_addr
*)lease
->hwaddr
) > addr6part(&context
->start6
) &&
641 addr6part((struct in6_addr
*)lease
->hwaddr
) <= addr6part(&context
->end6
) &&
642 addr6part((struct in6_addr
*)lease
->hwaddr
) > addr
)
643 addr
= addr6part((struct in6_addr
*)lease
->hwaddr
);
651 /* Find largest assigned address in context */
652 struct in_addr
lease_find_max_addr(struct dhcp_context
*context
)
654 struct dhcp_lease
*lease
;
655 struct in_addr addr
= context
->start
;
657 if (!(context
->flags
& (CONTEXT_STATIC
| CONTEXT_PROXY
)))
658 for (lease
= leases
; lease
; lease
= lease
->next
)
661 if (lease
->flags
& (LEASE_TA
| LEASE_NA
))
664 if (((unsigned)ntohl(lease
->addr
.s_addr
)) > ((unsigned)ntohl(context
->start
.s_addr
)) &&
665 ((unsigned)ntohl(lease
->addr
.s_addr
)) <= ((unsigned)ntohl(context
->end
.s_addr
)) &&
666 ((unsigned)ntohl(lease
->addr
.s_addr
)) > ((unsigned)ntohl(addr
.s_addr
)))
673 static struct dhcp_lease
*lease_allocate(void)
675 struct dhcp_lease
*lease
;
676 if (!leases_left
|| !(lease
= whine_malloc(sizeof(struct dhcp_lease
))))
679 memset(lease
, 0, sizeof(struct dhcp_lease
));
680 lease
->flags
= LEASE_NEW
;
682 #ifdef HAVE_BROKEN_RTC
683 lease
->length
= 0xffffffff; /* illegal value */
685 lease
->next
= leases
;
694 struct dhcp_lease
*lease4_allocate(struct in_addr addr
)
696 struct dhcp_lease
*lease
= lease_allocate();
698 lease
->hwaddr_len
= 256; /* illegal value */
704 struct dhcp_lease
*lease6_allocate(struct in6_addr
*addrp
, int lease_type
)
706 struct dhcp_lease
*lease
= lease_allocate();
707 memcpy(lease
->hwaddr
, addrp
, sizeof(*addrp
)) ;
708 lease
->flags
|= lease_type
;
714 void lease_set_expires(struct dhcp_lease
*lease
, unsigned int len
, time_t now
)
716 time_t exp
= now
+ (time_t)len
;
718 if (len
== 0xffffffff)
724 if (exp
!= lease
->expires
)
727 lease
->expires
= exp
;
728 #ifndef HAVE_BROKEN_RTC
729 lease
->flags
|= LEASE_AUX_CHANGED
;
734 #ifdef HAVE_BROKEN_RTC
735 if (len
!= lease
->length
)
738 lease
->flags
|= LEASE_AUX_CHANGED
;
744 void lease_set_hwaddr(struct dhcp_lease
*lease
, unsigned char *hwaddr
,
745 unsigned char *clid
, int hw_len
, int hw_type
, int clid_len
,
746 time_t now
, int force
)
750 lease
->flags
|= LEASE_HAVE_HWADDR
;
755 if (hw_len
!= lease
->hwaddr_len
||
756 hw_type
!= lease
->hwaddr_type
||
757 (hw_len
!= 0 && memcmp(lease
->hwaddr
, hwaddr
, hw_len
) != 0))
760 memcpy(lease
->hwaddr
, hwaddr
, hw_len
);
761 lease
->hwaddr_len
= hw_len
;
762 lease
->hwaddr_type
= hw_type
;
763 lease
->flags
|= LEASE_CHANGED
;
764 file_dirty
= 1; /* run script on change */
770 /* only update clid when one is available, stops packets
771 without a clid removing the record. Lease init uses
772 clid_len == 0 for no clid. */
773 if (clid_len
!= 0 && clid
)
778 if (lease
->clid_len
!= clid_len
)
780 lease
->flags
|= LEASE_AUX_CHANGED
;
783 if (!(lease
->clid
= whine_malloc(clid_len
)))
789 else if (memcmp(lease
->clid
, clid
, clid_len
) != 0)
791 lease
->flags
|= LEASE_AUX_CHANGED
;
798 lease
->clid_len
= clid_len
;
799 memcpy(lease
->clid
, clid
, clid_len
);
804 slaac_add_addrs(lease
, now
, force
);
808 static void kill_name(struct dhcp_lease
*lease
)
810 /* run script to say we lost our old name */
812 /* this shouldn't happen unless updates are very quick and the
813 script very slow, we just avoid a memory leak if it does. */
814 free(lease
->old_hostname
);
816 /* If we know the fqdn, pass that. The helper will derive the
817 unqualified name from it, free the unqualified name here. */
821 lease
->old_hostname
= lease
->fqdn
;
822 free(lease
->hostname
);
825 lease
->old_hostname
= lease
->hostname
;
827 lease
->hostname
= lease
->fqdn
= NULL
;
830 void lease_set_hostname(struct dhcp_lease
*lease
, char *name
, int auth
, char *domain
, char *config_domain
)
832 struct dhcp_lease
*lease_tmp
;
833 char *new_name
= NULL
, *new_fqdn
= NULL
;
835 if (config_domain
&& (!domain
|| !hostname_isequal(domain
, config_domain
)))
836 my_syslog(MS_DHCP
| LOG_WARNING
, _("Ignoring domain %s for DHCP host name %s"), config_domain
, name
);
838 if (lease
->hostname
&& name
&& hostname_isequal(lease
->hostname
, name
))
841 lease
->flags
|= LEASE_AUTH_NAME
;
845 if (!name
&& !lease
->hostname
)
848 /* If a machine turns up on a new net without dropping the old lease,
849 or two machines claim the same name, then we end up with two interfaces with
850 the same name. Check for that here and remove the name from the old lease.
851 Note that IPv6 leases are different. All the leases to the same DUID are
852 allowed the same name.
854 Don't allow a name from the client to override a name from dnsmasq config. */
858 if ((new_name
= whine_malloc(strlen(name
) + 1)))
860 strcpy(new_name
, name
);
861 if (domain
&& (new_fqdn
= whine_malloc(strlen(new_name
) + strlen(domain
) + 2)))
863 strcpy(new_fqdn
, name
);
864 strcat(new_fqdn
, ".");
865 strcat(new_fqdn
, domain
);
869 /* Depending on mode, we check either unqualified name or FQDN. */
870 for (lease_tmp
= leases
; lease_tmp
; lease_tmp
= lease_tmp
->next
)
872 if (option_bool(OPT_DHCP_FQDN
))
874 if (!new_fqdn
|| !lease_tmp
->fqdn
|| !hostname_isequal(lease_tmp
->fqdn
, new_fqdn
))
879 if (!new_name
|| !lease_tmp
->hostname
|| !hostname_isequal(lease_tmp
->hostname
, new_name
) )
883 if (lease
->flags
& (LEASE_TA
| LEASE_NA
))
885 if (!(lease_tmp
->flags
& (LEASE_TA
| LEASE_NA
)))
888 /* another lease for the same DUID is OK for IPv6 */
889 if (lease
->clid_len
== lease_tmp
->clid_len
&&
890 lease
->clid
&& lease_tmp
->clid
&&
891 memcmp(lease
->clid
, lease_tmp
->clid
, lease
->clid_len
) == 0)
894 else if (lease_tmp
->flags
& (LEASE_TA
| LEASE_NA
))
897 if ((lease_tmp
->flags
& LEASE_AUTH_NAME
) && !auth
)
904 kill_name(lease_tmp
);
912 lease
->hostname
= new_name
;
913 lease
->fqdn
= new_fqdn
;
916 lease
->flags
|= LEASE_AUTH_NAME
;
920 lease
->flags
|= LEASE_CHANGED
; /* run script on change */
923 void lease_set_interface(struct dhcp_lease
*lease
, int interface
, time_t now
)
925 if (lease
->last_interface
== interface
)
928 lease
->last_interface
= interface
;
929 lease
->flags
|= LEASE_CHANGED
;
932 slaac_add_addrs(lease
, now
, 0);
936 void rerun_scripts(void)
938 struct dhcp_lease
*lease
;
940 for (lease
= leases
; lease
; lease
= lease
->next
)
941 lease
->flags
|= LEASE_CHANGED
;
944 /* deleted leases get transferred to the old_leases list.
945 remove them here, after calling the lease change
946 script. Also run the lease change script on new/modified leases.
948 Return zero if nothing to do. */
949 int do_script_run(time_t now
)
951 struct dhcp_lease
*lease
;
954 /* If we're going to be sending DBus signals, but the connection is not yet up,
955 delay everything until it is. */
956 if (option_bool(OPT_DBUS
) && !daemon
->dbus
)
964 /* If the lease still has an old_hostname, do the "old" action on that first */
965 if (lease
->old_hostname
)
968 queue_script(ACTION_OLD_HOSTNAME
, lease
, lease
->old_hostname
, now
);
970 free(lease
->old_hostname
);
971 lease
->old_hostname
= NULL
;
977 struct slaac_address
*slaac
, *tmp
;
978 for (slaac
= lease
->slaac_address
; slaac
; slaac
= tmp
)
986 queue_script(ACTION_DEL
, lease
, lease
->old_hostname
, now
);
989 emit_dbus_signal(ACTION_DEL
, lease
, lease
->old_hostname
);
991 old_leases
= lease
->next
;
993 free(lease
->old_hostname
);
995 free(lease
->extradata
);
1002 /* make sure we announce the loss of a hostname before its new location. */
1003 for (lease
= leases
; lease
; lease
= lease
->next
)
1004 if (lease
->old_hostname
)
1007 queue_script(ACTION_OLD_HOSTNAME
, lease
, lease
->old_hostname
, now
);
1009 free(lease
->old_hostname
);
1010 lease
->old_hostname
= NULL
;
1014 for (lease
= leases
; lease
; lease
= lease
->next
)
1015 if ((lease
->flags
& (LEASE_NEW
| LEASE_CHANGED
)) ||
1016 ((lease
->flags
& LEASE_AUX_CHANGED
) && option_bool(OPT_LEASE_RO
)))
1019 queue_script((lease
->flags
& LEASE_NEW
) ? ACTION_ADD
: ACTION_OLD
, lease
,
1020 lease
->fqdn
? lease
->fqdn
: lease
->hostname
, now
);
1023 emit_dbus_signal((lease
->flags
& LEASE_NEW
) ? ACTION_ADD
: ACTION_OLD
, lease
,
1024 lease
->fqdn
? lease
->fqdn
: lease
->hostname
);
1026 lease
->flags
&= ~(LEASE_NEW
| LEASE_CHANGED
| LEASE_AUX_CHANGED
);
1028 /* this is used for the "add" call, then junked, since they're not in the database */
1029 free(lease
->extradata
);
1030 lease
->extradata
= NULL
;
1035 return 0; /* nothing to do */
1039 void lease_add_extradata(struct dhcp_lease
*lease
, unsigned char *data
, unsigned int len
, int delim
)
1043 /* check for embeded NULLs */
1044 for (i
= 0; i
< len
; i
++)
1051 if ((lease
->extradata_size
- lease
->extradata_len
) < (len
+ 1))
1053 size_t newsz
= lease
->extradata_len
+ len
+ 100;
1054 unsigned char *new = whine_malloc(newsz
);
1059 if (lease
->extradata
)
1061 memcpy(new, lease
->extradata
, lease
->extradata_len
);
1062 free(lease
->extradata
);
1065 lease
->extradata
= new;
1066 lease
->extradata_size
= newsz
;
1070 memcpy(lease
->extradata
+ lease
->extradata_len
, data
, len
);
1071 lease
->extradata
[lease
->extradata_len
+ len
] = delim
;
1072 lease
->extradata_len
+= len
+ 1;
1078 void tomato_helper(time_t now
)
1083 struct dhcp_lease
*lease
;
1085 // if delete exists...
1086 if ((f
= fopen("/var/tmp/dhcp/delete", "r")) != NULL
) {
1087 while (fgets(buf
, sizeof(buf
), f
)) {
1088 ia
.s_addr
= inet_addr(buf
);
1089 lease
= lease_find_by_addr(ia
);
1091 lease_prune(lease
, 0);
1092 lease_update_file(now
);
1096 unlink("/var/tmp/dhcp/delete");
1099 // dump the leases file
1100 if ((f
= fopen("/var/tmp/dhcp/leases.!", "w")) != NULL
) {
1101 for (lease
= leases
; lease
; lease
= lease
->next
) {
1102 if (lease
->hwaddr_type
== ARPHRD_ETHER
) {
1103 fprintf(f
, "%lu %02X:%02X:%02X:%02X:%02X:%02X %s %s\n",
1104 lease
->expires
- now
,
1105 lease
->hwaddr
[0], lease
->hwaddr
[1], lease
->hwaddr
[2], lease
->hwaddr
[3], lease
->hwaddr
[4], lease
->hwaddr
[5],
1106 inet_ntoa(lease
->addr
),
1107 ((lease
->hostname
) && (strlen(lease
->hostname
) > 0)) ? lease
->hostname
: "*");
1111 rename("/var/tmp/dhcp/leases.!", "/var/tmp/dhcp/leases");
1115 void flush_lease_file(time_t now
)
1118 lease_update_file(now
);