36 static void maybe_return_agent_options(
struct packet *
packet,
44 #if defined(DELAYED_ACK) 45 static void delayed_ack_enqueue(
struct lease *);
46 static void delayed_acks_timer(
void *);
49 struct leasequeue *ackqueue_head, *ackqueue_tail;
51 static struct timeval max_fsync;
60 static char dhcp_message [256];
61 static int site_code_min;
63 static int find_min_site_code(
struct universe *);
64 static isc_result_t lowest_site_code(
const void *,
unsigned,
void *);
66 static const char *dhcp_type_names [] = {
77 "DHCPLEASEUNASSIGNED",
84 # define send_packet trace_packet_send 94 memset (&client_identifier, 0,
sizeof client_identifier);
100 packet, (
struct lease *)0,
109 return "\"no client id\"";
119 packet -> raw -> hlen,
120 packet -> raw -> chaddr);
137 errmsg =
"unknown network segment";
149 log_info(
"%s from %s via %s: %s", s,
152 :
"<no identifier>"),
188 cip.
len =
sizeof packet -> raw -> ciaddr;
189 memcpy (cip.
iabuf, &packet -> raw -> ciaddr,
190 sizeof packet -> raw -> ciaddr);
205 if (lease -> uid_len) {
215 memset (&data, 0,
sizeof data);
217 packet, (
struct lease *)0,
223 if (lease -> uid_len != data.
len ||
224 memcmp (lease -> uid, data.
data, data.
len)) {
230 if ((lease -> hardware_addr.hbuf [0] !=
231 packet -> raw -> htype) ||
232 (lease -> hardware_addr.hlen - 1 !=
233 packet -> raw -> hlen) ||
234 memcmp (&lease -> hardware_addr.hbuf [1],
235 packet -> raw -> chaddr,
236 packet -> raw -> hlen))
265 switch (packet -> packet_type) {
299 errmsg =
"unknown packet type";
304 lease_dereference (&lease,
MDL);
315 int peer_has_leases = 0;
316 #if defined (FAILOVER_PROTOCOL) 317 dhcp_failover_state_t *peer;
323 0, &peer_has_leases, (
struct lease *)0,
MDL);
330 s =
"Hostname Unsuitable for Printing";
337 snprintf (msgbuf,
sizeof msgbuf,
"DHCPDISCOVER from %s %s%s%svia %s",
338 (packet -> raw -> htype
342 :
"<no identifier>")),
343 s ?
"(" :
"", s ? s :
"", s ?
") " :
"",
344 packet -> raw ->
giaddr.s_addr
345 ? inet_ntoa (packet -> raw ->
giaddr)
346 : packet -> interface -> name);
350 log_info (
"Packet from unknown subnet: %s",
351 inet_ntoa (packet -> raw ->
giaddr));
355 #if defined (FAILOVER_PROTOCOL) 356 if (lease && lease ->
pool && lease ->
pool -> failover_peer) {
357 peer = lease ->
pool -> failover_peer;
377 #if defined (DEBUG_FIND_LEASE) 382 lease_dereference (&lease,
MDL);
393 log_error (
"%s: peer holds all free leases",
396 log_error (
"%s: network %s: no free leases",
403 #if defined (FAILOVER_PROTOCOL) 404 if (lease && lease ->
pool && lease ->
pool -> failover_peer) {
405 peer = lease ->
pool -> failover_peer;
409 msgbuf, peer -> nrr);
413 peer = (dhcp_failover_state_t *)0;
418 if (peer_has_leases) {
419 log_debug (
"%s: load balance to peer %s",
420 msgbuf, peer -> name);
423 log_debug (
"%s: cancel load balance to peer %s - %s",
424 msgbuf, peer -> name,
"no free leases");
430 if (lease -> ends < cur_time && lease ->
scope)
436 if (when < lease ->
ends)
437 when = lease ->
ends;
443 lease_dereference (&lease,
MDL);
451 struct
lease *ip_lease;
463 #if defined (FAILOVER_PROTOCOL) 464 dhcp_failover_state_t *peer;
466 int have_requested_addr = 0;
472 memset (&data, 0,
sizeof data);
481 have_requested_addr = 1;
485 memcpy (cip.
iabuf, &packet -> raw -> ciaddr.s_addr, 4);
491 subnet = (
struct subnet *)0;
492 lease = (
struct lease *)0;
502 s =
"Hostname Unsuitable for Printing";
508 memset (&data, 0,
sizeof data);
520 sprintf (smbuf,
" (%s)",
piaddr (sip));
529 snprintf (msgbuf,
sizeof msgbuf,
530 "DHCPREQUEST for %s%s from %s %s%s%svia %s",
532 (packet -> raw -> htype
536 :
"<no identifier>")),
537 s ?
"(" :
"", s ? s :
"", s ?
") " :
"",
538 packet -> raw ->
giaddr.s_addr
539 ? inet_ntoa (packet -> raw ->
giaddr)
540 : packet -> interface -> name);
542 #if defined (FAILOVER_PROTOCOL) 543 if (lease && lease ->
pool && lease ->
pool -> failover_peer) {
544 peer = lease ->
pool -> failover_peer;
548 msgbuf, peer -> nrr);
573 log_debug (
"%s: lease owned by peer", msgbuf);
587 log_debug(
"%s: lease in transition state %s", msgbuf,
589 ?
"released" :
"expired");
598 log_debug (
"%s: lease reset by administrator", msgbuf);
612 (memcmp(sip.
iabuf,
"\0\0\0\0", sip.
len) != 0)) {
620 if (memcmp(sip.
iabuf, &from, sip.
len) != 0) {
621 log_debug(
"%s: not our server id", msgbuf);
650 peer = (dhcp_failover_state_t *)0;
696 (packet -> raw -> ciaddr.s_addr &&
697 packet -> raw ->
giaddr.s_addr) ||
698 (have_requested_addr && !packet -> raw -> ciaddr.s_addr)) {
704 if (subnet && subnet ->
group -> authoritative) {
705 log_info (
"%s: wrong network.", msgbuf);
710 log_info (
"%s: ignored (%s).", msgbuf,
712 ?
"not authoritative" :
"unknown subnet"));
719 subnet_dereference (&subnet,
MDL);
724 log_info (
"%s: wrong network.", msgbuf);
728 log_info (
"%s: ignored (not authoritative).", msgbuf);
735 if (!lease && ours) {
753 subnet_dereference (&subnet,
MDL);
755 lease_dereference (&lease,
MDL);
763 struct lease *
lease = (
struct lease *)0, *
next = (
struct lease *)0;
768 char msgbuf [1024], cstr[16];
777 log_info (
"DHCPRELEASE from %s specified requested-address.",
786 memset (&data, 0,
sizeof data);
799 lease_reference (&next, lease -> n_uid,
MDL);
800 if (!memcmp (&packet -> raw -> ciaddr,
804 lease_dereference (&lease,
MDL);
806 lease_reference (&lease, next,
MDL);
807 lease_dereference (&next,
MDL);
811 lease_dereference (&next,
MDL);
819 memcpy (cip.
iabuf, &packet -> raw -> ciaddr, 4);
826 (lease -> hardware_addr.hlen != packet -> raw -> hlen + 1 ||
827 lease -> hardware_addr.hbuf [0] != packet -> raw -> htype ||
828 memcmp (&lease -> hardware_addr.hbuf [1],
829 packet -> raw -> chaddr, packet -> raw -> hlen)))
830 lease_dereference (&lease,
MDL);
832 if (lease && lease -> client_hostname) {
833 if ((strlen (lease -> client_hostname) <= 64) &&
835 s = lease -> client_hostname;
837 s =
"Hostname Unsuitable for Printing";
845 strncpy(cstr, inet_ntoa (packet -> raw -> ciaddr), 15);
851 snprintf (msgbuf,
sizeof msgbuf,
852 "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
854 (packet -> raw -> htype
858 :
"<no identifier>")),
859 s ?
"(" :
"", s ? s :
"", s ?
") " :
"",
860 packet -> raw ->
giaddr.s_addr
861 ? inet_ntoa (packet -> raw ->
giaddr)
862 : packet -> interface -> name,
863 lease ?
"" :
"not ");
865 #if defined (FAILOVER_PROTOCOL) 866 if (lease && lease ->
pool && lease ->
pool -> failover_peer) {
867 dhcp_failover_state_t *peer = lease ->
pool -> failover_peer;
871 peer -> name, peer -> nrr);
885 if (lease && lease -> ends >
cur_time) {
889 #if defined(FAILOVER_PROTOCOL) 893 lease_dereference (&lease,
MDL);
919 memset (&data, 0,
sizeof data);
932 if (lease && lease -> client_hostname) {
933 if ((strlen (lease -> client_hostname) <= 64) &&
935 s = lease -> client_hostname;
937 s =
"Hostname Unsuitable for Printing";
944 snprintf (msgbuf,
sizeof msgbuf,
945 "DHCPDECLINE of %s from %s %s%s%svia %s",
947 (packet -> raw -> htype
951 :
"<no identifier>")),
952 s ?
"(" :
"", s ? s :
"", s ?
") " :
"",
953 packet -> raw ->
giaddr.s_addr
954 ? inet_ntoa (packet -> raw ->
giaddr)
955 : packet -> interface -> name);
962 packet->options, options,
968 for (i = packet -> class_count; i > 0; i--) {
970 (NULL, packet, NULL, NULL, packet->options, options,
980 packet -> options, options,
981 &lease -> scope, oc,
MDL)) {
984 #if defined (FAILOVER_PROTOCOL) 985 if (lease ->
pool && lease ->
pool -> failover_peer) {
986 dhcp_failover_state_t *peer =
987 lease ->
pool -> failover_peer;
992 peer -> name, peer -> nrr);
1004 status =
"abandoned";
1006 status =
"not found";
1012 log_info (
"%s: %s", msgbuf, status);
1014 #if defined(FAILOVER_PROTOCOL) 1020 lease_dereference (&lease,
MDL);
1029 char msgbuf[1024], *addr_type;
1034 struct packet outgoing;
1037 struct iaddr cip, gip, sip;
1040 struct sockaddr_in to;
1041 struct in_addr from;
1042 isc_boolean_t zeroed_ciaddr;
1044 int result, h_m_client_ip = 0;
1045 struct host_decl *host = NULL, *hp = NULL, *h;
1046 #if defined (DEBUG_INFORM_HOST) 1047 int h_w_fixed_addr = 0;
1055 if (!packet->raw->ciaddr.s_addr) {
1056 zeroed_ciaddr = ISC_TRUE;
1058 memcpy(cip.
iabuf, &packet->client_addr.iabuf, 4);
1059 addr_type =
"source";
1061 zeroed_ciaddr = ISC_FALSE;
1063 memcpy(cip.
iabuf, &packet->raw->ciaddr, 4);
1064 addr_type =
"client";
1069 if (packet->raw->giaddr.s_addr) {
1071 memcpy(gip.
iabuf, &packet->raw->giaddr, 4);
1072 if (zeroed_ciaddr == ISC_TRUE) {
1073 addr_type =
"relay";
1082 snprintf(msgbuf,
sizeof(msgbuf),
"DHCPINFORM from %s via %s",
1084 packet->raw->giaddr.s_addr ?
1085 inet_ntoa(packet->raw->giaddr) :
1086 packet->interface->name);
1089 if (!memcmp(cip.
iabuf,
"\0\0\0", 4)) {
1090 log_info(
"%s: ignored (null source address).", msgbuf);
1105 memset(&d1, 0,
sizeof d1);
1107 packet->options, NULL,
1112 log_info(
"%s: ignored (invalid subnet selection option).", msgbuf);
1134 if ((zeroed_ciaddr == ISC_TRUE) && (gip.
len != 0))
1135 addr_type =
"relay link select";
1137 addr_type =
"selected";
1142 if (subnet == NULL) {
1143 log_info(
"%s: unknown subnet for %s address %s",
1144 msgbuf, addr_type,
piaddr(sip));
1155 log_info(
"%s: not authoritative for subnet %s",
1156 msgbuf,
piaddr (subnet -> net));
1158 log_info(
"If this DHCP server is authoritative for%s",
1160 log_info(
"please write an `authoritative;' directi%s",
1161 "ve either in the");
1162 log_info(
"subnet declaration or in some scope that%s",
1164 log_info(
"subnet declaration - for example, write %s",
1166 log_info(
"of the dhcpd.conf file.");
1170 subnet_dereference(&subnet,
MDL);
1175 memset(&outgoing, 0,
sizeof outgoing);
1176 memset(&raw, 0,
sizeof raw);
1177 outgoing.
raw = &raw;
1179 maybe_return_agent_options(packet, options);
1183 packet->options, options,
1188 for (i = packet->class_count; i > 0; i--) {
1190 packet->options, options,
1192 packet->classes[i - 1]->group,
1215 memset(&d1, 0,
sizeof(d1));
1218 packet->options, NULL,
1223 #if defined (DEBUG_INFORM_HOST) 1225 log_debug (
"dhcpinform: found host by ID " 1226 "-- checking fixed-address match");
1230 for (h = hp; !h_m_client_ip && h; h = h->n_ipaddr) {
1234 memset(&fixed_addr, 0,
sizeof(fixed_addr));
1236 NULL, NULL, NULL, NULL,
1238 h->fixed_addr,
MDL))
1241 #if defined (DEBUG_INFORM_HOST) 1245 (i + cip.
len) <= fixed_addr.
len;
1247 if (memcmp(fixed_addr.
data + i,
1249 #if defined (DEBUG_INFORM_HOST) 1251 "host with matching " 1252 "fixed-address by ID");
1254 host_reference(&host, h,
MDL);
1263 for (h = hp; !host && h; h = h->
n_ipaddr) {
1267 #if defined (DEBUG_INFORM_HOST) 1269 "without fixed-address by ID");
1271 host_reference(&host, h,
MDL);
1275 host_dereference (&hp,
MDL);
1277 if (!host || !h_m_client_ip) {
1279 packet->raw->chaddr,
1280 packet->raw->hlen,
MDL);
1282 #if defined (DEBUG_INFORM_HOST) 1284 log_debug (
"dhcpinform: found host by HW " 1285 "-- checking fixed-address match");
1290 for (h = hp; !h_m_client_ip && h; h = h->n_ipaddr) {
1294 memset (&fixed_addr, 0,
sizeof(fixed_addr));
1296 NULL, NULL, NULL, NULL,
1298 h->fixed_addr,
MDL))
1301 #if defined (DEBUG_INFORM_HOST) 1305 (i + cip.
len) <= fixed_addr.
len;
1307 if (memcmp(fixed_addr.
data + i,
1309 #if defined (DEBUG_INFORM_HOST) 1311 "host with matching " 1312 "fixed-address by HW");
1320 host_dereference(&host,
MDL);
1321 host_reference(&host, h,
MDL);
1329 for (h = hp; !host && h; h = h->
n_ipaddr) {
1333 #if defined (DEBUG_INFORM_HOST) 1334 log_debug (
"dhcpinform: found host without " 1335 "fixed-address by HW");
1337 host_reference (&host, h,
MDL);
1342 host_dereference (&hp,
MDL);
1345 #if defined (DEBUG_INFORM_HOST) 1350 if (h_w_fixed_addr && !h_m_client_ip) {
1351 log_info (
"dhcpinform: matching host with " 1352 "fixed-address different than " 1353 "client IP detected?!");
1361 #if defined (DEBUG_INFORM_HOST) 1362 log_info (
"dhcpinform: applying host (group) options");
1365 packet->options, options,
1369 host_dereference (&host,
MDL);
1375 memset (&d1, 0,
sizeof d1);
1383 if (i >=
sizeof(raw.
file)) {
1384 log_info(
"file name longer than packet field " 1385 "truncated - field: %lu name: %d %.*s",
1386 (
unsigned long)
sizeof(raw.
file), i,
1388 i =
sizeof(raw.
file);
1403 if (i >=
sizeof(raw.
sname)) {
1404 log_info(
"server name longer than packet field " 1405 "truncated - field: %lu name: %d %.*s",
1406 (
unsigned long)
sizeof(raw.
sname), i,
1408 i =
sizeof(raw.
sname);
1429 &dhcpack, 1, 0, 0,
MDL)) {
1430 option_code_hash_lookup(&oc->
option,
1447 subnet -> netmask.iabuf,
1448 subnet -> netmask.len,
1450 option_code_hash_lookup(&oc->
option,
1465 packet -> options, options,
1470 (
const char *)d1.
data, d1.
len,
1475 subnet_dereference (&subnet,
MDL);
1479 options -> site_universe = u ->
index;
1487 memset (&prl, 0,
sizeof prl);
1504 packet -> options, options,
1509 dump_raw ((
unsigned char *)packet -> raw, packet -> packet_length);
1519 packet -> options, options,
1552 raw.
ciaddr = packet -> raw -> ciaddr;
1553 memcpy (raw.
chaddr, packet -> raw -> chaddr,
sizeof raw.
chaddr);
1554 raw.
hlen = packet -> raw -> hlen;
1555 raw.
htype = packet -> raw -> htype;
1557 raw.
xid = packet -> raw -> xid;
1558 raw.
secs = packet -> raw -> secs;
1559 raw.
flags = packet -> raw -> flags;
1560 raw.
hops = packet -> raw -> hops;
1569 to.sin_family = AF_INET;
1571 to.sin_len =
sizeof to;
1573 memset (to.sin_zero, 0,
sizeof to.sin_zero);
1594 memcpy(&to.sin_addr, gip.
iabuf, 4);
1599 memcpy(&to.sin_addr, cip.
iabuf, 4);
1604 snprintf(msgbuf,
sizeof msgbuf,
"DHCPACK to %s (%s) via",
piaddr(cip),
1605 (packet->raw->htype && packet->raw->hlen) ?
1607 "<no client hardware address>");
1609 packet->interface->name);
1613 : packet -> interface);
1615 outgoing.packet_length, from, &to, NULL);
1617 log_error ("%s:%d: Failed to send %d byte long packet over %s "
1618 "interface.", MDL, outgoing.packet_length,
1624 subnet_dereference (&subnet, MDL);
1626 TRACE(DHCPD_INFORM_DONE());
1642 struct packet *packet;
1644 struct
group *network_group;
1646 struct sockaddr_in to;
1647 struct in_addr from;
1651 struct packet outgoing;
1660 memset (&outgoing, 0,
sizeof outgoing);
1661 memset (&raw, 0,
sizeof raw);
1666 log_error (
"No memory for DHCPNAK message type.");
1672 log_error (
"No memory for expr_const expression.");
1685 log_error (
"No memory for DHCPNAK message type.");
1690 (
unsigned char *)dhcp_message,
1691 strlen (dhcp_message), 1, 0,
MDL)) {
1692 log_error (
"No memory for expr_const expression.");
1708 #if defined(SERVER_ID_FOR_NAK) 1735 for (i = packet->class_count; i > 0; i--) {
1737 packet->options, eval_options,
1739 packet->classes[i - 1]->group,
1761 memcpy (raw.
chaddr, packet -> raw -> chaddr,
sizeof raw.
chaddr);
1762 raw.
hlen = packet -> raw -> hlen;
1763 raw.
htype = packet -> raw -> htype;
1765 raw.
xid = packet -> raw -> xid;
1766 raw.
secs = packet -> raw -> secs;
1768 raw.
hops = packet -> raw -> hops;
1772 log_info (
"DHCPNAK on %s to %s via %s",
1775 packet -> raw ->
giaddr.s_addr
1776 ? inet_ntoa (packet -> raw ->
giaddr)
1777 : packet -> interface -> name);
1781 dump_raw ((
unsigned char *)packet -> raw, packet -> packet_length);
1787 to.sin_family = AF_INET;
1789 to.sin_len =
sizeof to;
1791 memset (to.sin_zero, 0,
sizeof to.sin_zero);
1800 to.sin_addr = raw.
giaddr;
1801 if (raw.
giaddr.s_addr != htonl (INADDR_LOOPBACK))
1806 if (fallback_interface) {
1807 result =
send_packet(fallback_interface, packet, &raw,
1811 log_error (
"%s:%d: Failed to send %d byte long " 1812 "packet over %s interface.",
MDL,
1814 fallback_interface->name);
1825 result =
send_packet(packet->interface, packet, &raw,
1828 log_error (
"%s:%d: Failed to send %d byte long packet over %s " 1830 packet->interface->name);
1855 struct packet *packet;
1866 NULL, packet->options,
1868 (lease ? &lease->
scope : NULL),
1874 packet->sv_echo_client_id = ISC_TRUE;
1878 memset(&client_id, 0,
sizeof client_id);
1881 packet->options, NULL,
1882 (lease ? &lease->
scope : NULL),
1891 option_code_hash_lookup(&oc->
option,
1906 struct packet *packet;
1913 int used, count, high_threshold, poolhigh = 0, poollow = 0;
1914 char *shared_name =
"no name";
1942 log_error(
"Pool threshold reset - shared subnet: %s; " 1943 "address: %s; low threshold %d/%d.",
1959 if ((poolhigh <= 0) || (poolhigh > 100)) {
1966 if (used < high_threshold) {
1972 log_error(
"Pool threshold exceeded - shared subnet: %s; " 1973 "address: %s; high threshold %d%% %d/%d.",
1975 poolhigh, used, count);
1991 if (poollow < poolhigh) {
1998 struct packet *packet;
2011 TIME offered_lease_time;
2013 TIME min_lease_time;
2017 isc_result_t result;
2020 struct in_addr from;
2021 TIME remaining_time;
2023 #if defined(DELAYED_ACK) 2025 isc_boolean_t enqueue = ISC_FALSE;
2027 int use_old_lease = 0;
2041 lease_cltt = lease->
cltt;
2045 host_reference (&host, hp,
MDL);
2046 else if (lease -> host)
2047 host_reference (&host, lease -> host,
MDL);
2052 log_fatal (
"unable to allocate lease state!");
2060 state -> got_server_identifier = 1;
2062 maybe_return_agent_options(packet, state->
options);
2086 NULL, packet->options,
2093 packet->options, state->
options,
2100 for (i = packet -> class_count; i > 0; i--) {
2102 packet->options, state->
options,
2104 packet->classes[i - 1]->group,
2126 state -> options, &lease -> scope,
2131 seek = (
struct lease *)0;
2136 if (seek == lease && !seek ->
n_uid) {
2137 lease_dereference (&seek,
MDL);
2140 next = (
struct lease *)0;
2144 next = (
struct lease *)0;
2147 lease_reference (&next, seek ->
n_uid,
MDL);
2148 if (seek != lease &&
2155 lease_dereference (&seek,
MDL);
2157 lease_reference (&seek, next,
MDL);
2158 lease_dereference (&next,
MDL);
2162 lease_dereference (&next,
MDL);
2165 lease_dereference (&seek,
MDL);
2172 !host -> client_identifier.len &&
2182 seek = (
struct lease *)0;
2188 if (seek == lease && !seek ->
n_hw) {
2189 lease_dereference (&seek,
MDL);
2192 next = (
struct lease *)0;
2195 lease_reference (&next, seek ->
n_hw,
MDL);
2196 if (seek != lease &&
2203 lease_dereference (&seek,
MDL);
2205 lease_reference (&seek, next,
MDL);
2206 lease_dereference (&next,
MDL);
2210 lease_dereference (&next,
MDL);
2213 lease_dereference (&seek,
MDL);
2223 memset (&d1, 0,
sizeof d1);
2229 packet -> options, state -> options,
2232 ntohs (packet -> raw -> secs) < d1.
data [0]) {
2233 log_info(
"%s: configured min-secs value (%d) " 2234 "is greater than secs field (%d). " 2235 "message dropped.", msg, d1.
data[0],
2236 ntohs(packet->raw->secs));
2240 host_dereference (&host,
MDL);
2266 packet -> options, state -> options,
2267 &lease -> scope, oc,
MDL)) {
2270 for (h = hp; h; h = h ->
n_ipaddr) {
2271 if (!h -> fixed_addr)
2275 host_reference (&host, h,
MDL);
2277 host_dereference(&hp,
MDL);
2281 packet -> raw -> htype,
2282 packet -> raw -> chaddr,
2283 packet -> raw -> hlen,
2285 for (h = hp; h; h = h ->
n_ipaddr) {
2286 if (!h -> fixed_addr)
2290 host_reference (&host, h,
MDL);
2292 host_dereference(&hp,
MDL);
2296 packet->options,
MDL);
2297 for (h = hp; h; h = h ->
n_ipaddr) {
2298 if (!h -> fixed_addr)
2302 host_reference (&host, h,
MDL);
2304 host_dereference(&hp,
MDL);
2312 packet->options, state->
options,
2329 &lease -> scope, oc,
MDL)) {
2331 log_info (
"%s: unknown client", msg);
2334 host_dereference (&host,
MDL);
2347 &lease -> scope, oc,
MDL)) {
2349 log_info (
"%s: bootp disallowed", msg);
2352 host_dereference (&host,
MDL);
2365 &lease -> scope, oc,
MDL)) {
2367 log_info (
"%s: booting disallowed", msg);
2370 host_dereference (&host,
MDL);
2379 if (lease -> billing_class) {
2381 if (packet -> classes [i] ==
2382 lease -> billing_class)
2384 if (i == packet -> class_count) {
2399 for (i = 0; i < packet->class_count; i++) {
2400 struct class *billclass, *subclass;
2402 billclass = packet->classes[i];
2409 if (subclass == NULL)
2410 cname = subclass->
name;
2412 cname = billclass->
name;
2415 if (bill != 0 && i == packet->class_count) {
2416 log_info(
"%s: no available billing: lease " 2417 "limit reached in all matching " 2418 "classes (last: '%s')", msg, cname);
2421 host_dereference(&host,
MDL);
2451 packet -> options, state -> options,
2452 &lease -> scope, oc,
MDL);
2460 packet -> options, state -> options,
2461 &lease -> scope, oc,
MDL);
2466 lt = (
struct lease *)0;
2467 result = lease_allocate (<,
MDL);
2468 if (result != ISC_R_SUCCESS) {
2469 log_info (
"%s: can't allocate temporary lease structure: %s",
2470 msg, isc_result_totext (result));
2473 host_dereference (&host,
MDL);
2497 if (d1.
len == sizeof (u_int32_t))
2498 default_lease_time =
2514 if (s1 && (d1.
len == 4)) {
2515 u_int32_t ones = 0xffffffff;
2541 if ((memcmp(d1.
data, &ones, 4) == 0) &&
2546 lease, NULL, packet->options,
2552 "reservation made on %s.",
2572 if (d1.
len == sizeof (u_int32_t))
2581 || lease_time > max_lease_time)
2585 if (min_lease_time > max_lease_time)
2595 if (d1.
len == sizeof (u_int32_t))
2605 memset(&d1, 0,
sizeof(d1));
2610 packet->options, state->
options,
2612 if (d1.
len == 1 && d1.
data[0] > 0 &&
2615 int poolfilled, total, count;
2618 adaptive_time = min_lease_time;
2630 poolfilled = (total > (INT_MAX / 100)) ?
2631 total / (count / 100) :
2632 (total * 100) / count;
2634 log_debug(
"Adap-lease: Total: %d, Free: %d, " 2635 "Ends: %d, Adaptive: %d, Fill: %d, " 2640 (
int)adaptive_time, poolfilled,
2643 if (poolfilled >= d1.
data[0] &&
2644 lease_time > adaptive_time) {
2645 log_info(
"Pool over threshold, time " 2646 "for %s reduced from %d to " 2649 (
int)adaptive_time);
2651 lease_time = adaptive_time;
2673 lease_dereference (<,
MDL);
2675 host_dereference (&host,
MDL);
2703 lease_dereference (<,
MDL);
2705 host_dereference (&host,
MDL);
2709 if (lease_time > remaining_time)
2710 lease_time = remaining_time;
2713 if (lease_time < min_lease_time) {
2715 lease_time = min_lease_time;
2721 #if defined (FAILOVER_PROTOCOL) 2724 if (lease ->
pool && lease ->
pool -> failover_peer) {
2725 TIME new_lease_time = lease_time;
2726 dhcp_failover_state_t *peer =
2727 lease ->
pool -> failover_peer;
2736 if (lease_time > peer->mclt) {
2744 new_lease_time = peer->mclt;
2746 (lt->
tsfp + peer->mclt))
2760 (new_lease_time / 2);
2773 lease_time = new_lease_time;
2780 state -> offered_expiry =
MAX_TIME - 1;
2782 state -> offered_expiry =
cur_time + lease_time;
2786 lt ->
ends = state -> offered_expiry;
2806 if (d1.
len == sizeof (u_int32_t))
2819 if (d1.
len == sizeof (u_int32_t))
2826 lt ->
ends = state -> offered_expiry = cur_time + lease_time;
2838 packet->options, state->
options,
2849 packet->options, state->
options,
2857 unsigned char *tuid;
2873 host_reference (< -> host, host,
MDL);
2874 host_dereference (&host,
MDL);
2876 if (lease -> subnet)
2877 subnet_reference (< -> subnet, lease -> subnet,
MDL);
2890 if (lease ->
scope) {
2918 if (!packet->agent_options_stashed &&
2919 (packet->options != NULL) &&
2959 }
else if (oc && s1) {
2962 log_error (
"no memory for client hostname.");
2974 sizeof packet -> raw -> chaddr);
2991 if ((!offer || offer ==
DHCPACK) &&
3004 if (lease ->
flags & STATIC_LEASE) {
3010 packet -> raw -> chaddr,
3011 sizeof packet -> raw -> chaddr);
3013 int commit = (!offer || (offer ==
DHCPACK));
3017 use_old_lease = reuse_lease(packet, lt, lease, state, offer);
3018 if (use_old_lease == 1) {
3022 #if !defined(DELAYED_ACK) 3031 if ((use_old_lease == 0) &&
3051 if ((use_old_lease == 0) &&
3053 !offer || offer ==
DHCPACK, 0, 0)) {
3055 log_info (
"%s: database update failed", msg);
3057 lease_dereference (<,
MDL);
3061 lease_dereference (<,
MDL);
3068 state -> ciaddr = packet -> raw -> ciaddr;
3069 state -> xid = packet -> raw -> xid;
3070 state -> secs = packet -> raw -> secs;
3071 state -> bootp_flags = packet -> raw ->
flags;
3072 state -> hops = packet -> raw -> hops;
3073 state -> offer = offer;
3081 packet -> options, state -> options,
3092 packet -> options, state -> options,
3094 if (d1.
len == sizeof (u_int16_t))
3103 packet -> options, state -> options,
3105 if (d1.
len == sizeof (u_int16_t))
3106 state -> max_message_size =
3137 if (state -> offer) {
3142 &state -> offer, 1, 0, 0,
MDL)) {
3143 option_code_hash_lookup(&oc->
option,
3147 state -> options, oc);
3154 memcpy(state->
from.
iabuf, &from,
sizeof(from));
3155 state->
from.
len =
sizeof(from);
3157 offered_lease_time =
3158 state -> offered_expiry -
cur_time;
3166 option_code_hash_lookup(&oc->
option,
3170 state -> options, oc);
3183 packet->options, state->
options,
3188 if (rebind_time >= offered_lease_time)
3192 offered_lease_time = rebind_time;
3200 packet->options, state->
options,
3210 if (state ->
ip -> address_count) {
3212 sizeof state ->
ip -> addresses [0];
3213 memcpy (state -> from.iabuf,
3214 &state ->
ip -> addresses [0],
3220 memset (&state -> siaddr, 0,
sizeof state -> siaddr);
3226 packet -> options, state -> options,
3227 &lease -> scope, oc,
MDL)) {
3231 memcpy (&state -> siaddr, d1.
data, 4);
3243 lease -> subnet -> netmask.iabuf,
3244 lease -> subnet -> netmask.len,
3246 option_code_hash_lookup(&oc->
option,
3250 state -> options, oc);
3270 (&ignorep, packet, lease, NULL,
3278 h = gethostbyaddr ((
char *)&ia,
sizeof ia, AF_INET);
3280 log_error (
"No hostname for %s", inet_ntoa (ia));
3287 strlen (h -> h_name) + 1,
3289 option_code_hash_lookup(&oc->
option,
3293 state -> options, oc);
3306 packet -> options, state -> options, &lease -> scope,
3318 option_code_hash_lookup(&oc->
option,
3322 state -> options, oc);
3335 packet -> options, state -> options,
3336 &lease -> scope, oc,
MDL)) {
3340 (
const char *)d1.
data, d1.
len,
3346 state -> options -> site_universe = u ->
index;
3368 packet -> options, state -> options,
3369 &lease -> scope, oc,
MDL);
3373 dump_raw ((
unsigned char *)packet -> raw, packet -> packet_length);
3376 lease -> state = state;
3385 if (offer ==
DHCPOFFER && !(lease -> flags & STATIC_LEASE) &&
3393 &lease -> scope, oc,
MDL))) {
3403 &lease -> scope, oc,
MDL)) {
3404 if (d1.
len == sizeof (u_int32_t))
3414 log_debug (
"Ping timeout: %ld", (
long)ping_timeout);
3423 tv.tv_sec =
cur_tv.tv_sec + ping_timeout;
3424 tv.tv_usec =
cur_tv.tv_usec;
3431 #if defined(DELAYED_ACK) 3433 delayed_ack_enqueue(lease);
3441 #if defined(DELAYED_ACK) 3453 delayed_ack_enqueue(
struct lease *lease)
3459 if (free_ackqueue) {
3461 free_ackqueue = q->
next;
3466 log_fatal(
"delayed_ack_enqueue: no memory!");
3468 memset(q, 0,
sizeof *q);
3470 lease_reference(&q->
lease, lease,
MDL);
3471 q->
next = ackqueue_head;
3482 delayed_acks_timer(NULL);
3484 struct timeval next_fsync;
3486 if (max_fsync.tv_sec == 0 && max_fsync.tv_usec == 0) {
3489 max_fsync.tv_usec =
cur_tv.tv_usec +
3492 if (max_fsync.tv_usec >= 1000000) {
3494 max_fsync.tv_usec -= 1000000;
3499 next_fsync.tv_sec =
cur_tv.tv_sec;
3500 next_fsync.tv_usec =
cur_tv.tv_usec + min_ack_delay_usecs;
3501 if (next_fsync.tv_usec >= 1000000) {
3502 next_fsync.tv_sec++;
3503 next_fsync.tv_usec -= 1000000;
3506 if ((next_fsync.tv_sec > max_fsync.tv_sec) ||
3507 ((next_fsync.tv_sec == max_fsync.tv_sec) &&
3508 (next_fsync.tv_usec > max_fsync.tv_usec))) {
3509 next_fsync.tv_sec = max_fsync.tv_sec;
3510 next_fsync.tv_usec = max_fsync.tv_usec;
3513 add_timeout(&next_fsync, delayed_acks_timer, NULL,
3524 delayed_acks_timer(
void *foo)
3529 memset(&max_fsync, 0,
sizeof(max_fsync));
3531 if (!outstanding_acks) {
3546 for (ack = ackqueue_tail ; ack ; ack = p) {
3549 #if defined(FAILOVER_PROTOCOL) 3553 dhcp_failover_state_t *fpeer;
3556 if (fpeer && fpeer->link_to_peer) {
3564 log_error(
"delayed ack for %s has gone stale",
3570 lease_dereference(&ack->
lease,
MDL);
3571 ack->
next = free_ackqueue;
3572 free_ackqueue = ack;
3575 ackqueue_head = NULL;
3576 ackqueue_tail = NULL;
3577 outstanding_acks = 0;
3580 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) 3582 relinquish_ackqueue(
void)
3586 for (q = ackqueue_head ; q ; q = n) {
3590 for (q = free_ackqueue ; q ; q = n) {
3600 struct lease *lease;
3605 struct sockaddr_in to;
3606 struct in_addr from;
3610 int nulltp, bootpp, unicastp = 1;
3615 log_fatal (
"dhcp_reply was supplied lease with no state!");
3620 memset (&raw, 0,
sizeof raw);
3621 memset (&d1, 0,
sizeof d1);
3625 if (state -> filename.len && state -> filename.data) {
3627 state -> filename.data,
3628 state -> filename.len >
sizeof raw.
file 3629 ?
sizeof raw.
file : state -> filename.len);
3630 if (
sizeof raw.
file > state -> filename.len)
3631 memset (&raw.
file [state -> filename.len], 0,
3632 (
sizeof raw.
file) - state -> filename.len);
3634 log_info(
"file name longer than packet field " 3635 "truncated - field: %lu name: %d %.*s",
3636 (
unsigned long)
sizeof(raw.
file),
3637 state->filename.len, (
int)state->filename.len,
3638 state->filename.data);
3644 if (state -> server_name.len && state -> server_name.data) {
3646 state -> server_name.data,
3647 state -> server_name.len >
sizeof raw.
sname 3648 ?
sizeof raw.
sname : state -> server_name.len);
3649 if (
sizeof raw.
sname > state -> server_name.len)
3650 memset (&raw.
sname [state -> server_name.len], 0,
3651 (
sizeof raw.
sname) - state -> server_name.len);
3653 log_info(
"server name longer than packet field " 3654 "truncated - field: %lu name: %d %.*s",
3655 (
unsigned long)
sizeof(raw.
sname),
3663 &lease -> hardware_addr.hbuf [1],
sizeof raw.
chaddr);
3664 raw.
hlen = lease -> hardware_addr.hlen - 1;
3665 raw.
htype = lease -> hardware_addr.hbuf [0];
3681 packet_length =
cons_options (state -> packet, &raw, lease,
3683 state -> max_message_size,
3684 state -> packet -> options,
3686 bufs, nulltp, bootpp,
3687 &state -> parameter_request_list,
3690 memcpy (&raw.
ciaddr, &state -> ciaddr,
sizeof raw.
ciaddr);
3692 raw.
siaddr = state -> siaddr;
3695 raw.
xid = state -> xid;
3696 raw.
secs = state -> secs;
3697 raw.
flags = state -> bootp_flags;
3698 raw.
hops = state -> hops;
3701 if (lease -> client_hostname) {
3702 if ((strlen (lease -> client_hostname) <= 64) &&
3704 s = lease -> client_hostname;
3706 s =
"Hostname Unsuitable for Printing";
3711 log_info (
"%s on %s to %s %s%s%svia %s",
3713 ? (state -> offer ==
DHCPACK ?
"DHCPACK" :
"DHCPOFFER")
3716 (lease -> hardware_addr.hlen > 1
3718 lease -> hardware_addr.hlen - 1,
3719 &lease -> hardware_addr.hbuf [1])
3721 s ?
"(" :
"", s ? s :
"", s ?
") " :
"",
3723 ? inet_ntoa (state ->
giaddr)
3724 : state ->
ip -> name));
3727 hto.
hlen = lease -> hardware_addr.hlen;
3728 memcpy (hto.
hbuf, lease -> hardware_addr.hbuf, hto.
hlen);
3730 to.sin_family = AF_INET;
3732 to.sin_len =
sizeof to;
3734 memset (to.sin_zero, 0,
sizeof to.sin_zero);
3737 dump_raw ((
unsigned char *)&raw, packet_length);
3747 to.sin_addr = raw.
giaddr;
3748 if (raw.
giaddr.s_addr != htonl (INADDR_LOOPBACK))
3753 if (fallback_interface) {
3754 result =
send_packet(fallback_interface, NULL, &raw,
3755 packet_length, raw.
siaddr, &to,
3758 log_error (
"%s:%d: Failed to send %d byte long " 3759 "packet over %s interface.",
MDL,
3761 fallback_interface->name);
3781 }
else if (raw.
ciaddr.s_addr &&
3788 to.sin_addr = raw.
ciaddr;
3791 if (fallback_interface) {
3792 result =
send_packet(fallback_interface, NULL, &raw,
3793 packet_length, raw.
siaddr, &to,
3796 log_error(
"%s:%d: Failed to send %d byte long" 3797 " packet over %s interface.",
MDL,
3799 fallback_interface->name);
3813 to.sin_addr = raw.
yiaddr;
3824 memcpy (&from, state -> from.iabuf,
sizeof from);
3827 from, &to, unicastp ? &hto : NULL);
3829 log_error (
"%s:%d: Failed to send %d byte long " 3830 "packet over %s interface.",
MDL,
3831 packet_length, state->
ip->
name);
3846 int *peer_has_leases,
struct lease *ip_lease_in,
3849 struct lease *uid_lease = (
struct lease *)0;
3850 struct lease *ip_lease = (
struct lease *)0;
3851 struct lease *hw_lease = (
struct lease *)0;
3852 struct lease *lease = (
struct lease *)0;
3856 struct lease *fixed_lease = (
struct lease *)0;
3857 struct lease *next = (
struct lease *)0;
3860 int have_client_identifier = 0;
3866 #if defined(FAILOVER_PROTOCOL) 3868 if (peer_has_leases) {
3871 for (pool = share->
pools ; pool ; pool = pool->
next) {
3876 (peer->i_am == secondary && pool->
free_leases))) {
3877 *peer_has_leases = 1;
3884 if (packet -> raw -> ciaddr.s_addr) {
3886 memcpy (cip.
iabuf, &packet -> raw -> ciaddr, 4);
3891 memset (&d1, 0,
sizeof d1);
3898 packet -> got_requested_address = 1;
3913 memset (&client_identifier, 0,
sizeof client_identifier);
3916 packet, (
struct lease *)0,
3921 have_client_identifier = 1;
3926 client_identifier.
len,
MDL)) {
3928 packet -> known = 1;
3932 #if defined (DEBUG_FIND_LEASE) 3934 log_info (
"Found host for client identifier: %s.",
3940 host_reference (&host, hp,
MDL);
3941 host_dereference (&hp,
MDL);
3945 client_identifier.
len,
MDL);
3950 if (!fixed_lease && !host) {
3952 packet -> raw -> chaddr,
3953 packet -> raw -> hlen,
MDL)) {
3955 packet -> known = 1;
3957 host_dereference (&host,
MDL);
3958 host_reference (&host, hp,
MDL);
3959 host_dereference (&hp,
MDL);
3961 #if defined (DEBUG_FIND_LEASE) 3963 log_info (
"Found host for link address: %s.",
3972 if (!fixed_lease && !host) {
3977 host_dereference(&host,
MDL);
3978 host_reference(&host, hp,
MDL);
3979 host_dereference(&hp,
MDL);
3981 #if defined (DEBUG_FIND_LEASE) 3983 log_info (
"Found host via host-identifier");
3992 if (packet -> packet_type ==
DHCPREQUEST && fixed_lease &&
3998 strcpy (dhcp_message,
"requested address is incorrect");
3999 #if defined (DEBUG_FIND_LEASE) 4000 log_info (
"Client's fixed-address %s doesn't match %s%s",
4018 #if defined (DEBUG_FIND_LEASE) 4019 log_info (
"trying next lease matching client id: %s",
4023 #if defined (FAILOVER_PROTOCOL) 4035 #if defined (DEBUG_FIND_LEASE) 4036 log_info(
"not active or not mine to allocate: %s",
4044 #if defined (DEBUG_FIND_LEASE) 4045 log_info (
"wrong network segment: %s",
4055 #if defined (DEBUG_FIND_LEASE) 4060 if (uid_lease -> n_uid)
4061 lease_reference (&next,
4062 uid_lease -> n_uid,
MDL);
4063 if (!packet -> raw -> ciaddr.s_addr)
4065 lease_dereference (&uid_lease,
MDL);
4067 lease_reference (&uid_lease, next,
MDL);
4068 lease_dereference (&next,
MDL);
4074 #if defined (DEBUG_FIND_LEASE) 4076 log_info (
"Found lease for client id: %s.",
4087 h.
hlen = packet -> raw -> hlen + 1;
4088 h.
hbuf [0] = packet -> raw -> htype;
4089 memcpy (&h.
hbuf [1], packet -> raw -> chaddr, packet -> raw -> hlen);
4092 #if defined (DEBUG_FIND_LEASE) 4093 log_info (
"trying next lease matching hw addr: %s",
4096 #if defined (FAILOVER_PROTOCOL) 4109 #if defined (DEBUG_FIND_LEASE) 4110 log_info(
"not active or not mine to allocate: %s",
4123 if (hw_lease -> binding_state !=
FTS_FREE &&
4126 (!have_client_identifier ||
4127 hw_lease -> uid_len != client_identifier.
len ||
4128 memcmp (hw_lease -> uid, client_identifier.
data,
4129 hw_lease -> uid_len))) {
4130 #if defined (DEBUG_FIND_LEASE) 4131 log_info (
"wrong client identifier: %s",
4137 #if defined (DEBUG_FIND_LEASE) 4138 log_info (
"wrong network segment: %s",
4147 #if defined (DEBUG_FIND_LEASE) 4151 if (!packet -> raw -> ciaddr.s_addr)
4154 if (hw_lease -> n_hw)
4155 lease_reference (&next, hw_lease -> n_hw,
MDL);
4156 lease_dereference (&hw_lease,
MDL);
4158 lease_reference (&hw_lease, next,
MDL);
4159 lease_dereference (&next,
MDL);
4165 #if defined (DEBUG_FIND_LEASE) 4167 log_info (
"Found lease for hardware address: %s.",
4174 lease_reference (&ip_lease, ip_lease_in,
MDL);
4178 #if defined (DEBUG_FIND_LEASE) 4180 log_info (
"Found lease for requested address: %s.",
4187 if (ip_lease && ours)
4197 if (ip_lease && (ip_lease -> subnet ->
shared_network != share)) {
4200 #if defined (DEBUG_FIND_LEASE) 4201 log_info (
"...but it was on the wrong shared network.");
4203 strcpy (dhcp_message,
"requested address on bad subnet");
4204 lease_dereference (&ip_lease,
MDL);
4218 (!have_client_identifier ||
4219 ip_lease -> uid_len != client_identifier.
len ||
4220 memcmp (ip_lease -> uid, client_identifier.
data,
4221 ip_lease -> uid_len)) :
4222 (ip_lease -> hardware_addr.hbuf [0] != packet -> raw -> htype ||
4223 ip_lease -> hardware_addr.hlen != packet -> raw -> hlen + 1 ||
4224 memcmp (&ip_lease -> hardware_addr.hbuf [1],
4225 packet -> raw -> chaddr,
4226 (
unsigned)(ip_lease -> hardware_addr.hlen - 1))))) {
4235 if (ip_lease -> binding_state !=
FTS_FREE &&
4237 #if defined (DEBUG_FIND_LEASE) 4238 log_info (
"rejecting lease for requested address.");
4242 if (ours && ip_lease -> binding_state !=
FTS_ACTIVE)
4244 lease_dereference (&ip_lease,
MDL);
4252 if (ip_lease && (uid_lease || hw_lease) &&
4259 #if defined (DEBUG_FIND_LEASE) 4260 log_info(
"ip lease not active or not ours to offer.");
4262 lease_dereference(&ip_lease,
MDL);
4269 ip_lease->
uid && ip_lease != uid_lease) {
4270 if (have_client_identifier &&
4271 (ip_lease -> uid_len == client_identifier.
len) &&
4272 !memcmp (client_identifier.
data,
4273 ip_lease -> uid, ip_lease -> uid_len)) {
4276 log_error (
"client %s has duplicate%s on %s",
4279 (ip_lease -> subnet ->
4287 !packet -> raw -> ciaddr.s_addr &&
4293 lease_dereference (&uid_lease,
MDL);
4294 lease_reference (&uid_lease, ip_lease,
MDL);
4301 if (packet -> packet_type ==
DHCPREQUEST && fixed_lease) {
4302 lease_dereference (&fixed_lease,
MDL);
4304 log_error (
"Dynamic and static leases present for %s.",
4306 log_error (
"Remove host declaration %s or remove %s",
4307 (fixed_lease && fixed_lease -> host
4308 ? (fixed_lease -> host -> name
4309 ? fixed_lease -> host -> name
4313 log_error (
"from the dynamic address pool for %s",
4317 lease_dereference (&ip_lease,
MDL);
4318 strcpy (dhcp_message,
4319 "database conflict - call for help!");
4322 if (ip_lease && ip_lease != uid_lease) {
4323 #if defined (DEBUG_FIND_LEASE) 4324 log_info (
"requested address not available.");
4326 lease_dereference (&ip_lease,
MDL);
4332 if (packet -> packet_type ==
DHCPREQUEST && fixed_lease && ip_lease)
4336 if (hw_lease && hw_lease == uid_lease) {
4337 #if defined (DEBUG_FIND_LEASE) 4338 log_info (
"hardware lease and uid lease are identical.");
4340 lease_dereference (&hw_lease,
MDL);
4342 if (ip_lease && ip_lease == hw_lease) {
4343 lease_dereference (&hw_lease,
MDL);
4344 #if defined (DEBUG_FIND_LEASE) 4345 log_info (
"hardware lease and ip lease are identical.");
4348 if (ip_lease && ip_lease == uid_lease) {
4349 lease_dereference (&uid_lease,
MDL);
4350 #if defined (DEBUG_FIND_LEASE) 4351 log_info (
"uid lease and ip lease are identical.");
4365 lease_dereference (&ip_lease,
MDL);
4373 if (!packet -> raw -> ciaddr.s_addr)
4375 lease_dereference (&uid_lease,
MDL);
4383 if (!packet -> raw -> ciaddr.s_addr)
4385 lease_dereference (&hw_lease,
MDL);
4392 strcpy (dhcp_message,
"requested address not available");
4399 !ip_lease && !fixed_lease) {
4400 #if defined (DEBUG_FIND_LEASE) 4401 log_info (
"no applicable lease found for DHCPREQUEST.");
4409 lease_reference (&lease, fixed_lease,
MDL);
4410 lease_dereference (&fixed_lease,
MDL);
4411 #if defined (DEBUG_FIND_LEASE) 4412 log_info (
"choosing fixed address.");
4420 if (!packet -> raw -> ciaddr.s_addr)
4422 #if defined (DEBUG_FIND_LEASE) 4423 log_info (
"not choosing requested address (!).");
4426 #if defined (DEBUG_FIND_LEASE) 4427 log_info (
"choosing lease on requested address.");
4429 lease_reference (&lease, ip_lease,
MDL);
4431 host_dereference (&lease -> host,
MDL);
4433 lease_dereference (&ip_lease,
MDL);
4441 log_error(
"uid lease %s for client %s is duplicate " 4447 if (!packet -> raw -> ciaddr.s_addr &&
4451 #if defined (DEBUG_FIND_LEASE) 4452 log_info (
"not choosing uid lease.");
4455 lease_reference (&lease, uid_lease,
MDL);
4457 host_dereference (&lease -> host,
MDL);
4458 #if defined (DEBUG_FIND_LEASE) 4462 lease_dereference (&uid_lease,
MDL);
4468 #if defined (DEBUG_FIND_LEASE) 4469 log_info (
"not choosing hardware lease.");
4476 if (!hw_lease -> uid_len ||
4477 (have_client_identifier
4478 ? (hw_lease -> uid_len ==
4479 client_identifier.
len &&
4480 !memcmp (hw_lease -> uid,
4481 client_identifier.
data,
4482 client_identifier.
len))
4483 : packet -> packet_type == 0)) {
4484 lease_reference (&lease, hw_lease,
MDL);
4486 host_dereference (&lease -> host,
MDL);
4487 #if defined (DEBUG_FIND_LEASE) 4488 log_info (
"choosing hardware lease.");
4491 #if defined (DEBUG_FIND_LEASE) 4492 log_info (
"not choosing hardware lease: %s.",
4497 lease_dereference (&hw_lease,
MDL);
4506 if (lease && host && !lease->
host) {
4510 host_reference(&p, host,
MDL);
4529 host_reference(&lease->
host, p,
MDL);
4531 host_dereference(&p,
MDL);
4536 host_dereference(&p,
MDL);
4538 host_reference(&p, n,
MDL);
4539 host_dereference(&n,
MDL);
4550 lease == ip_lease &&
4552 log_error (
"Reclaiming REQUESTed abandoned IP address %s.",
4554 }
else if (lease && (lease -> binding_state ==
FTS_ABANDONED)) {
4561 lease_dereference (&lease,
MDL);
4565 if (have_client_identifier)
4569 lease_dereference (&fixed_lease,
MDL);
4571 lease_dereference (&hw_lease,
MDL);
4573 lease_dereference (&uid_lease,
MDL);
4575 lease_dereference (&ip_lease,
MDL);
4577 host_dereference (&host,
MDL);
4580 #if defined (DEBUG_FIND_LEASE) 4584 lease_reference (lp, lease, file, line);
4585 lease_dereference (&lease,
MDL);
4588 #if defined (DEBUG_FIND_LEASE) 4589 log_info (
"Not returning a lease.");
4604 struct lease *lease = (
struct lease *)0;
4607 if (lease_allocate (&lease,
MDL) != ISC_R_SUCCESS)
4609 if (host_reference (&rhp, hp,
MDL) != ISC_R_SUCCESS) {
4610 lease_dereference (&lease,
MDL);
4614 &rhp, &lease ->
ip_addr, share)) {
4615 lease_dereference (&lease,
MDL);
4616 host_dereference (&rhp,
MDL);
4619 host_reference (&lease -> host, rhp,
MDL);
4623 lease -> uid = lease -> uid_buf;
4624 if (!lease -> uid) {
4625 lease_dereference (&lease,
MDL);
4626 host_dereference (&rhp,
MDL);
4632 lease -> hardware_addr = rhp ->
interface;
4633 lease -> starts = lease -> cltt = lease -> ends =
MIN_TIME;
4637 lease_reference (lp, lease,
MDL);
4639 lease_dereference (&lease,
MDL);
4640 host_dereference (&rhp,
MDL);
4652 struct pool *
pool,
int *peer_has_leases)
4654 struct lease *lease = NULL;
4655 struct lease *candl = NULL;
4656 struct lease *peerl = NULL;
4658 for (;
pool ; pool = pool ->
next) {
4659 if ((pool -> prohibit_list &&
4660 permitted (packet, pool -> prohibit_list)) ||
4661 (pool -> permit_list &&
4662 !
permitted (packet, pool -> permit_list)))
4665 #if defined (FAILOVER_PROTOCOL) 4691 if (peerl != NULL) {
4692 if (((candl == NULL) ||
4697 *peer_has_leases = 1;
4704 if (peerl != NULL) {
4705 if (((candl == NULL) ||
4710 *peer_has_leases = 1;
4717 if ((candl == NULL) && (peerl != NULL) &&
4760 (candl -> ends < lease ->
ends))) {
4768 (candl -> ends < lease -> ends))) {
4774 if (candl -> ends < lease -> ends)
4778 if (lease != NULL) {
4780 log_error(
"Reclaiming abandoned lease %s.",
4788 if (lease->
host != NULL) {
4789 log_debug(
"soft impossible condition (%s:%d): stale " 4790 "host \"%s\" found on lease %s",
MDL,
4793 host_dereference(&lease->
host,
MDL);
4796 lease_reference (lp, lease,
MDL);
4808 struct packet *packet;
4809 struct
permit *permit_list;
4814 for (p = permit_list; p; p = p ->
next) {
4815 switch (p ->
type) {
4817 if (!packet -> known)
4822 if (packet -> known)
4827 if (packet -> authenticated)
4832 if (!packet -> authenticated)
4840 if (!packet -> options_valid ||
4841 !packet -> packet_type)
4847 if (p ->
class == packet -> classes [i])
4849 if (packet -> classes [i] &&
4850 packet -> classes [i] -> superclass &&
4851 (packet -> classes [i] -> superclass ==
4867 struct packet *packet;
4871 struct subnet *subnet = (
struct subnet *)0;
4887 if (!oc && !packet -> raw ->
giaddr.s_addr) {
4889 struct in_addr any_addr;
4890 any_addr.s_addr = INADDR_ANY;
4892 if (!packet -> packet_type && memcmp(&packet -> raw -> ciaddr, &any_addr, 4)) {
4894 memcpy(cip.
iabuf, &packet -> raw -> ciaddr, 4);
4913 memset (&data, 0,
sizeof data);
4921 if (data.
len != 4) {
4930 memcpy (ia.
iabuf, &packet->raw->ciaddr, 4);
4932 memcpy (ia.
iabuf, &packet->raw->giaddr, 4);
4939 subnet_dereference (&subnet,
MDL);
4984 struct packet *packet) {
4985 unsigned option_num;
4988 struct in_addr *a = NULL;
4989 isc_boolean_t found = ISC_FALSE;
4992 memset(&d, 0,
sizeof(d));
4993 memset(from, 0,
sizeof(*from));
5001 if (d.
len ==
sizeof(*from)) {
5003 memcpy(from, d.
data,
sizeof(*from));
5009 if ((out_options != NULL) &&
5010 (options != out_options)) {
5020 if ((found == ISC_FALSE) &&
5024 if (out_options != NULL) {
5032 (
unsigned char *)a,
sizeof(*a),
5033 0, allocate,
MDL)) {
5034 option_code_hash_lookup(&oc->
option,
5036 &option_num, 0,
MDL);
5068 struct packet *packet,
5069 struct group *network_group) {
5071 if (*network_options == NULL) {
5086 packet->
options, *network_options,
5092 packet->
options, *network_options,
5101 packet->
options, *network_options,
5107 }
else if (network_group != NULL) {
5109 packet->
options, *network_options,
5114 packet->
options, *network_options,
5131 find_min_site_code(
struct universe *u)
5141 site_code_min = 224;
5142 option_code_hash_foreach(u->
code_hash, lowest_site_code);
5144 if (site_code_min < 224) {
5145 log_error(
"WARNING: site-local option codes less than 224 have " 5146 "been deprecated by RFC3942. You have options " 5147 "listed in site local space %s that number as low as " 5148 "%d. Please investigate if these should be declared " 5149 "as regular options rather than site-local options, " 5150 "or migrated up past 224.",
5151 u->
name, site_code_min);
5158 if (site_code_min < 128)
5159 site_code_min = 128;
5168 return site_code_min;
5172 lowest_site_code(
const void *key,
unsigned len,
void *
object)
5176 if (option->
code < site_code_min)
5177 site_code_min = option->
code;
5179 return ISC_R_SUCCESS;
5183 maybe_return_agent_options(
struct packet *packet,
struct option_state *options)
5227 struct lease *lease,
5241 ((
unsigned char*)lease->
host->
name),
5245 option_code_hash_lookup(&oc->
option,
5286 reuse_lease (
struct packet* packet,
5287 struct lease* new_lease,
5288 struct lease* lease,
5299 (new_lease->
ddns_cb == NULL)) {
5311 if (d1.
len == 1 && (d1.
data[0] < 100))
5312 thresh = d1.
data[0];
5320 int lease_length = 0;
5325 if (lease_length <= (INT_MAX / thresh))
5326 limit = lease_length * thresh / 100;
5328 limit = lease_length / 100 * thresh;
5334 if (lease_age <= limit) {
5339 if (new_lease->
scope != NULL) {
5340 if (lease->
scope != NULL) {
5351 log_debug(
"reuse_lease: lease age %ld (secs)" 5352 " under %d%% threshold, reply with " 5353 "unaltered, existing lease",
#define DHCPD_DISCOVER_START()
int supersede_lease(struct lease *, struct lease *, int, int, int, int)
int find_grouped_subnet(struct subnet **, struct shared_network *, struct iaddr, const char *, int)
char * print_dotted_quads(unsigned len, const u_int8_t *data)
void unbill_class(struct lease *lease)
#define DHCPD_NAK_LEASE_START()
char sname[DHCP_SNAME_LEN]
struct binding_scope * global_scope
#define DEFAULT_MIN_ACK_DELAY_USECS
#define SV_MAX_LEASE_TIME
#define SV_USE_HOST_DECL_NAMES
#define SV_MIN_LEASE_TIME
void dhcpleasequery(struct packet *, int)
void save_option(struct universe *universe, struct option_state *options, struct option_cache *oc)
int executable_statement_dereference(struct executable_statement **ptr, const char *file, int line)
int find_host_for_network(struct subnet **, struct host_decl **, struct iaddr *, struct shared_network *)
struct shared_network * shared_network
const char * piaddr(const struct iaddr addr)
struct dhcp_ddns_cb * ddns_cb
#define DHO_PXE_CLIENT_ID
#define DHCPD_ACK_LEASE_DONE()
void * dmalloc(unsigned, const char *, int)
struct lease_state * state
struct class * superclass
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
#define DHCPD_ACK_LEASE_START()
#define DEFAULT_MIN_LEASE_TIME
struct universe server_universe
int execute_statements(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct executable_statement *statements, struct on_star *on_star)
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
char * print_hw_addr(int htype, const int hlen, const unsigned char *data) const
#define SV_IGNORE_CLIENT_UIDS
void cancel_timeout(void(*)(void *) where, void *what)
int find_hosts_by_option(struct host_decl **, struct packet *, struct option_state *, const char *, int)
#define print_hex_1(len, data, limit)
#define DHO_DHCP_PARAMETER_REQUEST_LIST
#define DEFAULT_ACK_DELAY_USECS
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
#define SV_BOOTP_LEASE_LENGTH
struct executable_statement * on_release
void lease_ping_timeout(void *)
#define DHO_DHCP_LEASE_TIME
struct in_addr * addresses
int option_reference(struct option **dest, struct option *src, const char *file, int line)
void dhcpack(struct packet *packet)
void dhcpdecline(struct packet *packet, int ms_nulltp)
struct universe dhcp_universe
struct interface_info * ip
#define SV_SITE_OPTION_SPACE
void data_string_forget(struct data_string *data, const char *file, int line)
#define FIND_PERCENT(count, percent)
struct option_cache * fixed_addr
struct class * billing_class
struct group * root_group
int mockup_lease(struct lease **lp, struct packet *packet, struct shared_network *share, struct host_decl *hp)
void delete_option(struct universe *universe, struct option_state *options, int code)
int log_error(const char *,...) __attribute__((__format__(__printf__
int binding_scope_dereference(struct binding_scope **ptr, const char *file, int line)
void add_timeout(struct timeval *when, void(*)(void *) where, void *what, tvref_t ref, tvunref_t unref)
void dump_packet(struct packet *)
void(* tvunref_t)(void *, const char *, int)
#define DHO_DHCP_REBINDING_TIME
dhcp_failover_state_t * failover_peer
void release_lease(struct lease *, struct packet *)
int find_hosts_by_haddr(struct host_decl **, int, const unsigned char *, unsigned, const char *, int)
void dhcprelease(struct packet *packet, int ms_nulltp)
struct expression * expression
struct data_string client_identifier
void(* tvref_t)(void *, void *, const char *, int)
const char * binding_state_print(enum failover_state state)
struct option_state * options
#define LEASE_NOT_EMPTY(LQ)
void nak_lease(struct packet *packet, struct iaddr *cip, struct group *network_group)
Constructs and sends a DHCP Nak.
#define DHO_DHCP_SERVER_IDENTIFIER
void log_fatal(const char *,...) __attribute__((__format__(__printf__
void dhcpdiscover(struct packet *packet, int ms_nulltp)
struct option_state * options
#define DEFAULT_DELAYED_ACK
int option_cache_allocate(struct option_cache **cptr, const char *file, int line)
#define SV_LOG_THRESHOLD_HIGH
#define DEFAULT_ACK_DELAY_SECS
int locate_network(struct packet *packet)
void free_lease_state(struct lease_state *, const char *, int)
universe_hash_t * universe_hash
void dhcp_reply(struct lease *lease)
struct hardware hardware_addr
#define SV_BOOTP_LEASE_CUTOFF
int find_subnet(struct subnet **sp, struct iaddr addr, const char *file, int line)
void execute_statements_in_scope(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct group *group, struct group *limiting_group, struct on_star *on_star)
struct interface_info * fallback_interface
#define FAILOVER_PROTOCOL
int option_state_allocate(struct option_state **ptr, const char *file, int line)
int evaluate_option_cache(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
struct permit * prohibit_list
int option_chain_head_dereference(struct option_chain_head **ptr, const char *file, int line)
void dhcp(struct packet *packet)
#define MS_NULL_TERMINATION
int packet_reference(struct packet **ptr, struct packet *bp, const char *file, int line)
#define SV_ALWAYS_BROADCAST
void abandon_lease(struct lease *, const char *)
binding_state_t binding_state
#define DEFAULT_MAX_LEASE_TIME
char * print_hw_addr_or_client_id(struct packet *packet)
struct interface_info * interface
char * print_client_identifier_from_packet(struct packet *packet)
int write_lease(struct lease *lease)
void putULong(unsigned char *, u_int32_t)
#define SV_ECHO_CLIENT_ID
#define SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE
#define DEFAULT_CACHE_THRESHOLD
int permitted(struct packet *packet, struct permit *permit_list)
int find_lease_by_hw_addr(struct lease **, const unsigned char *, unsigned, const char *, int)
#define DHCPD_INFORM_START()
void eval_network_statements(struct option_state **network_options, struct packet *packet, struct group *network_group)
Builds option set from statements at the global and network scope.
#define DEFAULT_DEFAULT_LEASE_TIME
void check_pool_threshold(struct packet *packet, struct lease *lease, struct lease_state *state)
#define SV_GET_LEASE_HOSTNAMES
ssize_t send_packet(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
int cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, struct lease *lease, struct client_state *client_state, int mms, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, int overload_avail, int terminate, int bootpp, struct data_string *prl, const char *vuname)
#define DHCPD_DECLINE_START()
void get_server_source_address(struct in_addr *from, struct option_state *options, struct option_state *out_options, struct packet *packet)
u_int32_t getUShort(const unsigned char *)
void dfree(void *, const char *, int)
struct host_decl * n_ipaddr
int option_chain_head_reference(struct option_chain_head **ptr, struct option_chain_head *bp, const char *file, int line)
int load_balance_mine(struct packet *, dhcp_failover_state_t *)
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
void echo_client_id(struct packet *packet, struct lease *lease, struct option_state *in_options, struct option_state *out_options)
Adds a dhcp-client-id option to a set of options Given a set of input options, it searches for echo-c...
struct in_addr limited_broadcast
int int log_info(const char *,...) __attribute__((__format__(__printf__
unsigned short cannot_reuse
u_int32_t getULong(const unsigned char *)
struct shared_network * shared_network
#define DHO_SUBNET_SELECTION
int find_hosts_by_uid(struct host_decl **, const unsigned char *, unsigned, const char *, int)
int allocate_lease(struct lease **lp, struct packet *packet, struct pool *pool, int *peer_has_leases)
#define DHCPD_FIND_LEASE_START()
#define DHO_DHCP_MAX_MESSAGE_SIZE
#define DHCPD_RELEASE_START()
struct universe ** universes
int option_state_dereference(struct option_state **ptr, const char *file, int line)
void ack_lease(struct packet *packet, struct lease *lease, unsigned int offer, TIME when, char *msg, int ms_nulltp, struct host_decl *hp)
struct shared_network * shared_network
int binding_scope_reference(struct binding_scope **ptr, struct binding_scope *bp, const char *file, int line)
int got_server_identifier
#define LEASE_GET_FIRST(LQ)
binding_state_t rewind_binding_state
int evaluate_boolean_option_cache(int *ignorep, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
int make_const_data(struct expression **expr, const unsigned char *data, unsigned len, int terminated, int allocate, const char *file, int line)
int ddns_updates(struct packet *, struct lease *, struct lease *, struct iasubopt *, struct iasubopt *, struct option_state *)
#define SV_BOOT_UNKNOWN_CLIENTS
#define DHCPLEASEUNASSIGNED
#define DEFAULT_PING_TIMEOUT
#define SV_LOG_THRESHOLD_LOW
int db_printable(const unsigned char *)
void use_host_decl_name(struct packet *packet, struct lease *lease, struct option_state *options)
Adds hostname option when use-host-decl-names is enabled.
isc_boolean_t agent_options_stashed
int find_lease(struct lease **lp, struct packet *packet, struct shared_network *share, int *ours, int *peer_has_leases, struct lease *ip_lease_in, const char *file, int line)
#define DHCPD_DISCOVER_DONE()
#define SV_CACHE_THRESHOLD
int find_lease_by_uid(struct lease **, const unsigned char *, unsigned, const char *, int)
void dhcpinform(struct packet *packet, int ms_nulltp)
int expression_reference(struct expression **ptr, struct expression *src, const char *file, int line)
#define DHCPD_REPLY_DONE()
#define SV_DEFAULT_LEASE_TIME
#define SV_ADAPTIVE_LEASE_TIME_THRESHOLD
#define SV_ONE_LEASE_PER_CLIENT
void dump_raw(unsigned char *buf, unsigned len) const
#define UNICAST_BROADCAST_HACK
#define DHCPD_DECLINE_DONE()
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
#define DHCPD_RELEASE_DONE()
int icmp_echorequest(struct iaddr *addr)
#define DHO_VENDOR_CLASS_IDENTIFIER
struct universe agent_universe
struct ipv6_pool ** pools
const int dhcp_type_name_max
option_code_hash_t * code_hash
#define DHO_DHCP_RENEWAL_TIME
struct executable_statement * on_expiry
struct shared_network * shared_network
#define DHO_DHCP_CLIENT_IDENTIFIER
struct permit * permit_list
struct data_string filename server_name
#define DHCPD_REQUEST_DONE()
int can_unicast_without_arp(struct interface_info *)
struct lease_state * new_lease_state(const char *, int)
int bill_class(struct lease *, struct class *)
isc_result_t dhcp_failover_send_updates(dhcp_failover_state_t *)
struct executable_statement * on_commit
const unsigned char * data
int get_option_int(int *result, struct universe *universe, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct option_state *options, struct binding_scope **scope, unsigned code, const char *file, int line)
#define DHO_DHCP_MESSAGE_TYPE
int bind_ds_value(struct binding_scope **scope, const char *name, struct data_string *value)
struct binding_scope * scope
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
struct hardware interface
int got_requested_address
int find_lease_by_ip_addr(struct lease **, struct iaddr, const char *, int)
void dhcprequest(struct packet *packet, int ms_nulltp, struct lease *ip_lease)
#define DHCPD_REQUEST_START()
#define SV_STASH_AGENT_OPTIONS
binding_state_t next_binding_state
struct interface_info * interface
#define DHCPD_NAK_LEASE_DONE()
void classify_client(struct packet *)
#define DHCPD_FIND_LEASE_DONE()
struct group_object * object
#define DHCPD_REPLY_START()
int lease_mine_to_reallocate(struct lease *)
#define DHO_DHCP_REQUESTED_ADDRESS
#define SV_RESERVE_INFINITE