Lines Matching +full:re +full:- +full:config

3 /*-
4 * SPDX-License-Identifier: BSD-3-Clause
50 * Consortium DHCP server uses. Much system-specific configuration code
53 * system-specific configuration code to these operating systems - instead,
102 static int nullfd = -1;
120 * the end of time (~2038 when a 32-bit time_t is being used).
122 #define TIME_MAX ((((time_t) 1 << (sizeof(time_t) * CHAR_BIT - 2)) - 1) * 2 + 1)
146 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
147 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
161 return -1;
170 if (sa->sa_family == AF_INET)
172 if (sa->sa_family == AF_INET6)
181 return (-1);
214 if (_ifi->client->active != NULL) {
217 _ifi->client->active);
218 if (_ifi->client->alias)
220 _ifi->client->alias);
223 _ifi->client->state = S_INIT;
244 if (n < (ssize_t)sizeof(rtm->rtm_msglen) ||
245 n < (ssize_t)rtm->rtm_msglen ||
246 rtm->rtm_version != RTM_VERSION)
249 switch (rtm->rtm_type) {
254 if (ifam->ifam_index != ifi->index)
256 if (findproto((char *)(ifam + 1), ifam->ifam_addrs) != AF_INET)
261 sa = (struct sockaddr_in*)get_ifa((char *)(ifam + 1), ifam->ifam_addrs);
267 memcpy(a.iabuf, &sa->sin_addr, a.len);
271 for (l = ifi->client->active; l != NULL; l = l->next)
272 if (addr_eq(a, l->address))
278 addr = inet_ntoa(sa->sin_addr);
279 if (rtm->rtm_type == RTM_NEWADDR) {
286 warning("My address (%s) was re-added", addr);
295 if (ifm->ifm_index != ifi->index)
297 if ((rtm->rtm_flags & RTF_UP) == 0) {
299 ifi->name);
302 linkstat = interface_link_status(ifi->name);
303 if (linkstat != ifi->linkstat) {
304 debug("%s link state %s -> %s", ifi->name,
305 ifi->linkstat ? "up" : "down",
307 ifi->linkstat = linkstat;
314 if (ifan->ifan_what == IFAN_DEPARTURE &&
315 ifan->ifan_index == ifi->index) {
317 ifi->name);
323 if (ifan->ifan_index != ifi->index)
325 switch (ifan->ifan_what) {
334 if (memcmp(curbssid, jev->iev_addr, 6)) {
338 memcpy(curbssid, jev->iev_addr, 6);
349 if (ifi->client->alias)
350 script_write_params("alias_", ifi->client->alias);
389 while ((ch = getopt(argc, argv, "bc:dl:np:qu")) != -1)
419 argc -= optind;
442 if (strlcpy(ifi->name, argv[0], IFNAMSIZ) >= IFNAMSIZ)
445 _PATH_DHCLIENT_DB, ifi->name) == -1)
460 /* The next bit is potentially very time-consuming, so write out
466 if (!interface_link_status(ifi->name)) {
467 fprintf(stderr, "%s: no link ...", ifi->name);
470 while (!interface_link_status(ifi->name)) {
481 ifi->linkstat = 1;
483 if ((nullfd = open(_PATH_DEVNULL, O_RDWR, 0)) == -1)
493 * Obtain hostname before entering capability mode - it won't be
500 if (ifi->client->alias)
501 priv_script_write_params("alias_", ifi->client->alias);
507 if (pipe(pipe_fd) == -1)
512 close(ifi->ufdesc);
513 ifi->ufdesc = -1;
514 close(ifi->wfdesc);
515 ifi->wfdesc = -1;
523 if ((fd = open(path_dhclient_db, O_RDONLY|O_EXLOCK|O_CREAT, 0)) == -1)
529 if ((routefd = socket(PF_ROUTE, SOCK_RAW, 0)) != -1)
539 setproctitle("%s", ifi->name);
542 if (setgroups(1, &pw->pw_gid) != 0)
554 if (chroot(_PATH_VAREMPTY) == -1)
556 if (chdir("/") == -1)
560 if (setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
561 seteuid(pw->pw_uid) || setuid(pw->pw_uid))
567 ifi->client->state = S_INIT;
582 fprintf(stderr, "usage: %s [-bdnqu] ", getprogname());
583 fprintf(stderr, "[-c conffile] [-l leasefile] interface\n");
592 * -> entering INIT state
593 * -> recvpacket_flag == 0: timeout in this state
594 * -> otherwise: received a packet in this state
601 * Several per-interface variables are used to keep track of the process:
608 * sendpacket: DHCP packet we're trying to send.
610 * In addition, there are several relevant per-lease variables.
623 if (!ip->client->active || ip->client->active->is_bootp) {
629 ip->client->state = S_REBOOTING;
634 ip->client->xid = arc4random();
636 /* Make a DHCPREQUEST packet, and set appropriate per-interface
638 make_request(ip, ip->client->active);
639 ip->client->destination = iaddr_broadcast;
640 ip->client->first_sending = cur_time;
641 ip->client->interval = ip->client->config->initial_interval;
644 ip->client->medium = NULL;
661 /* Make a DHCPDISCOVER packet, and set appropriate per-interface
663 make_discover(ip, ip->client->active);
664 ip->client->xid = ip->client->packet.xid;
665 ip->client->destination = iaddr_broadcast;
666 ip->client->state = S_SELECTING;
667 ip->client->first_sending = cur_time;
668 ip->client->interval = ip->client->config->initial_interval;
696 for (lp = ip->client->offered_leases; lp; lp = next) {
697 next = lp->next;
702 script_init("ARPCHECK", lp->medium);
715 picked->next = NULL;
721 ip->client->offered_leases = NULL;
726 ip->client->state = S_INIT;
732 if (!picked->options[DHO_DHCP_MESSAGE_TYPE].len) {
733 ip->client->new = picked;
737 ip->client->new->expiry = cur_time + 12000;
738 ip->client->new->renewal += cur_time + 8000;
739 ip->client->new->rebind += cur_time + 10000;
741 ip->client->state = S_REQUESTING;
749 ip->client->destination = iaddr_broadcast;
750 ip->client->state = S_REQUESTING;
751 ip->client->first_sending = cur_time;
752 ip->client->interval = ip->client->config->initial_interval;
756 ip->client->xid = ip->client->packet.xid;
758 /* Toss the lease we picked - we'll get it back in a DHCPACK. */
771 struct interface_info *ip = packet->interface;
774 /* If we're not receptive to an offer right now, or if the offer
776 if (packet->interface->client->xid != packet->raw->xid ||
777 (packet->interface->hw_address.hlen != packet->raw->hlen) ||
778 (memcmp(packet->interface->hw_address.haddr,
779 packet->raw->chaddr, packet->raw->hlen)))
782 if (ip->client->state != S_REBOOTING &&
783 ip->client->state != S_REQUESTING &&
784 ip->client->state != S_RENEWING &&
785 ip->client->state != S_REBINDING)
788 note("DHCPACK from %s", piaddr(packet->client_addr));
796 ip->client->new = lease;
802 if (ip->client->config->default_actions[DHO_DHCP_LEASE_TIME] ==
804 ip->client->new->expiry = getULong(
805 ip->client->config->defaults[DHO_DHCP_LEASE_TIME].data);
806 else if (ip->client->new->options[DHO_DHCP_LEASE_TIME].len >= 4)
807 ip->client->new->expiry = getULong(
808 ip->client->new->options[DHO_DHCP_LEASE_TIME].data);
810 ip->client->new->expiry = default_lease_time;
814 if (ip->client->new->expiry < 0 ||
815 ip->client->new->expiry > TIME_MAX - cur_time)
816 ip->client->new->expiry = TIME_MAX - cur_time;
818 if (ip->client->new->expiry < 60)
819 ip->client->new->expiry = 60;
821 /* Unless overridden in the config, take the server-provided renewal
825 if (ip->client->config->default_actions[DHO_DHCP_RENEWAL_TIME] ==
827 ip->client->new->renewal = getULong(
828 ip->client->config->defaults[DHO_DHCP_RENEWAL_TIME].data);
829 else if (ip->client->new->options[DHO_DHCP_RENEWAL_TIME].len >= 4)
830 ip->client->new->renewal = getULong(
831 ip->client->new->options[DHO_DHCP_RENEWAL_TIME].data);
833 ip->client->new->renewal = ip->client->new->expiry / 2;
834 if (ip->client->new->renewal < 0 ||
835 ip->client->new->renewal > ip->client->new->expiry / 2)
836 ip->client->new->renewal = ip->client->new->expiry / 2;
839 if (ip->client->config->default_actions[DHO_DHCP_REBINDING_TIME] ==
841 ip->client->new->rebind = getULong(
842 ip->client->config->defaults[DHO_DHCP_REBINDING_TIME].data);
843 else if (ip->client->new->options[DHO_DHCP_REBINDING_TIME].len >= 4)
844 ip->client->new->rebind = getULong(
845 ip->client->new->options[DHO_DHCP_REBINDING_TIME].data);
847 ip->client->new->rebind = ip->client->new->renewal / 4 * 7;
848 if (ip->client->new->rebind < 0 ||
849 ip->client->new->rebind > ip->client->new->renewal / 4 * 7)
850 ip->client->new->rebind = ip->client->new->renewal / 4 * 7;
852 /* Convert the time offsets into seconds-since-the-epoch */
853 ip->client->new->expiry += cur_time;
854 ip->client->new->renewal += cur_time;
855 ip->client->new->rebind += cur_time;
866 ip->client->new->medium = ip->client->medium;
868 opt = &ip->client->new->options[DHO_INTERFACE_MTU];
869 if (opt->len == sizeof(u_int16_t)) {
872 bool supersede = (ip->client->config->default_actions[DHO_INTERFACE_MTU] ==
876 mtu = getUShort(ip->client->config->defaults[DHO_INTERFACE_MTU].data);
878 mtu = be16dec(opt->data);
880 if (ip->client->active) {
881 opt = &ip->client->active->options[DHO_INTERFACE_MTU];
882 if (opt->len == sizeof(u_int16_t)) {
883 old_mtu = be16dec(opt->data);
892 } else if (ip->client->state != S_RENEWING || mtu != old_mtu) {
898 write_client_lease(ip, ip->client->new, 0);
901 script_init((ip->client->state == S_REQUESTING ? "BOUND" :
902 (ip->client->state == S_RENEWING ? "RENEW" :
903 (ip->client->state == S_REBOOTING ? "REBOOT" : "REBIND"))),
904 ip->client->new->medium);
905 if (ip->client->active && ip->client->state != S_REBOOTING)
906 script_write_params("old_", ip->client->active);
907 script_write_params("new_", ip->client->new);
908 if (ip->client->alias)
909 script_write_params("alias_", ip->client->alias);
913 if (ip->client->active)
914 free_client_lease(ip->client->active);
915 ip->client->active = ip->client->new;
916 ip->client->new = NULL;
919 add_timeout(ip->client->active->renewal, state_bound, ip);
921 note("bound to %s -- renewal in %d seconds.",
922 piaddr(ip->client->active->address),
923 (int)(ip->client->active->renewal - cur_time));
924 ip->client->state = S_BOUND;
945 make_request(ip, ip->client->active);
946 ip->client->xid = ip->client->packet.xid;
948 if (ip->client->config->default_actions[DHO_DHCP_SERVER_IDENTIFIER] ==
950 dp = ip->client->config->defaults[DHO_DHCP_SERVER_IDENTIFIER].data;
951 len = ip->client->config->defaults[DHO_DHCP_SERVER_IDENTIFIER].len;
953 dp = ip->client->active->options[DHO_DHCP_SERVER_IDENTIFIER].data;
954 len = ip->client->active->options[DHO_DHCP_SERVER_IDENTIFIER].len;
957 memcpy(ip->client->destination.iabuf, dp, len);
958 ip->client->destination.len = len;
960 ip->client->destination = iaddr_broadcast;
962 ip->client->first_sending = cur_time;
963 ip->client->interval = ip->client->config->initial_interval;
964 ip->client->state = S_RENEWING;
975 if (packet->raw->op != BOOTREPLY)
980 for (ap = packet->interface->client->config->reject_list;
981 ap; ap = ap->next) {
982 if (addr_eq(packet->client_addr, ap->addr)) {
983 note("BOOTREPLY from %s rejected.", piaddr(ap->addr));
997 switch (packet->packet_type) {
1016 for (ap = packet->interface->client->config->reject_list;
1017 ap; ap = ap->next) {
1018 if (addr_eq(packet->client_addr, ap->addr)) {
1019 note("%s from %s rejected.", type, piaddr(ap->addr));
1029 struct interface_info *ip = packet->interface;
1037 const char *name = packet->options[DHO_DHCP_MESSAGE_TYPE].len ?
1040 /* If we're not receptive to an offer right now, or if the offer
1042 if (ip->client->state != S_SELECTING ||
1043 packet->interface->client->xid != packet->raw->xid ||
1044 (packet->interface->hw_address.hlen != packet->raw->hlen) ||
1045 (memcmp(packet->interface->hw_address.haddr,
1046 packet->raw->chaddr, packet->raw->hlen)))
1049 note("%s from %s", name, piaddr(packet->client_addr));
1053 for (i = 0; ip->client->config->required_options[i]; i++) {
1054 if (!packet->options[ip->client->config->
1062 for (lease = ip->client->offered_leases;
1063 lease; lease = lease->next) {
1064 if (lease->address.len == sizeof(packet->raw->yiaddr) &&
1065 !memcmp(lease->address.iabuf,
1066 &packet->raw->yiaddr, lease->address.len)) {
1080 if (!packet->options[DHO_DHCP_MESSAGE_TYPE].len)
1081 lease->is_bootp = 1;
1084 lease->medium = ip->client->medium;
1087 script_init("ARPSEND", lease->medium);
1097 /* Figure out when we're supposed to stop selecting. */
1099 ip->client->first_sending + ip->client->config->select_interval;
1103 if (lease->address.len == ip->client->requested_address.len &&
1104 !memcmp(lease->address.iabuf,
1105 ip->client->requested_address.iabuf,
1106 ip->client->requested_address.len)) {
1107 lease->next = ip->client->offered_leases;
1108 ip->client->offered_leases = lease;
1112 then don't extend the timeout - just hope for the
1118 if (ip->client->offered_leases &&
1123 lease->next = NULL;
1124 if (!ip->client->offered_leases)
1125 ip->client->offered_leases = lease;
1127 for (lp = ip->client->offered_leases; lp->next;
1128 lp = lp->next)
1130 lp->next = lease;
1134 /* If we're supposed to stop selecting before we've had time
1163 struct interface_info *ip = packet->interface;
1178 if (packet->options[i].len) {
1180 for (j = 0; ip->client->config->ignored_options[j]; j++)
1182 ip->client->config->ignored_options[j]) {
1188 lease->options[i].data =
1189 malloc(packet->options[i].len + 1);
1190 if (!lease->options[i].data) {
1195 memcpy(lease->options[i].data,
1196 packet->options[i].data,
1197 packet->options[i].len);
1198 lease->options[i].len =
1199 packet->options[i].len;
1200 lease->options[i].data[lease->options[i].len] =
1205 warning("Invalid lease option - ignoring offer");
1212 lease->address.len = sizeof(packet->raw->yiaddr);
1213 memcpy(lease->address.iabuf, &packet->raw->yiaddr, lease->address.len);
1215 lease->nextserver.len = sizeof(packet->raw->siaddr);
1216 memcpy(lease->nextserver.iabuf, &packet->raw->siaddr, lease->nextserver.len);
1220 RFC 2131 merely states that sname is NUL-terminated (which do
1224 if ((!packet->options[DHO_DHCP_OPTION_OVERLOAD].len ||
1225 !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)) &&
1226 packet->raw->sname[0]) {
1227 lease->server_name = malloc(DHCP_SNAME_LEN + 1);
1228 if (!lease->server_name) {
1233 memcpy(lease->server_name, packet->raw->sname, DHCP_SNAME_LEN);
1234 lease->server_name[DHCP_SNAME_LEN]='\0';
1238 if ((!packet->options[DHO_DHCP_OPTION_OVERLOAD].len ||
1239 !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1)) &&
1240 packet->raw->file[0]) {
1242 lease->filename = malloc(DHCP_FILE_LEN + 1);
1243 if (!lease->filename) {
1248 memcpy(lease->filename, packet->raw->file, DHCP_FILE_LEN);
1249 lease->filename[DHCP_FILE_LEN]='\0';
1257 struct interface_info *ip = packet->interface;
1259 /* If we're not receptive to an offer right now, or if the offer
1261 if (packet->interface->client->xid != packet->raw->xid ||
1262 (packet->interface->hw_address.hlen != packet->raw->hlen) ||
1263 (memcmp(packet->interface->hw_address.haddr,
1264 packet->raw->chaddr, packet->raw->hlen)))
1267 if (ip->client->state != S_REBOOTING &&
1268 ip->client->state != S_REQUESTING &&
1269 ip->client->state != S_RENEWING &&
1270 ip->client->state != S_REBINDING)
1273 note("DHCPNAK from %s", piaddr(packet->client_addr));
1275 if (!ip->client->active) {
1280 free_client_lease(ip->client->active);
1281 ip->client->active = NULL;
1286 ip->client->state = S_INIT;
1301 interval = cur_time - ip->client->first_sending;
1303 /* If we're past the panic timeout, call the script and tell it
1305 if (interval > ip->client->config->timeout) {
1310 /* If we're selecting media, try the whole list before doing
1313 if (!ip->client->offered_leases &&
1314 ip->client->config->media) {
1317 if (ip->client->medium) {
1318 ip->client->medium = ip->client->medium->next;
1321 if (!ip->client->medium) {
1323 error("No valid media types for %s!", ip->name);
1324 ip->client->medium = ip->client->config->media;
1328 note("Trying medium \"%s\" %d", ip->client->medium->string,
1330 script_init("MEDIUM", ip->client->medium);
1336 * If we're supposed to increase the interval, do so. If it's
1343 if (!ip->client->interval)
1344 ip->client->interval =
1345 ip->client->config->initial_interval;
1347 ip->client->interval += (arc4random() >> 2) %
1348 (2 * ip->client->interval);
1352 if (ip->client->interval >
1353 ip->client->config->backoff_cutoff)
1354 ip->client->interval =
1355 ((ip->client->config->backoff_cutoff / 2)
1357 ip->client->config->backoff_cutoff));
1358 } else if (!ip->client->interval)
1359 ip->client->interval =
1360 ip->client->config->initial_interval;
1364 if (cur_time + ip->client->interval >
1365 ip->client->first_sending + ip->client->config->timeout)
1366 ip->client->interval =
1367 (ip->client->first_sending +
1368 ip->client->config->timeout) - cur_time + 1;
1372 ip->client->packet.secs = htons(interval);
1374 ip->client->packet.secs = htons(65535);
1375 ip->client->secs = ip->client->packet.secs;
1378 ip->name, inet_ntoa(inaddr_broadcast), REMOTE_PORT,
1379 (int)ip->client->interval);
1382 send_packet_unpriv(privfd, &ip->client->packet,
1383 ip->client->packet_length, inaddr_any, inaddr_broadcast);
1385 add_timeout(cur_time + ip->client->interval, send_discover, ip);
1398 struct client_lease *loop = ip->client->active;
1405 if (!ip->client->active && ip->client->leases)
1409 while (ip->client->active) {
1410 if (ip->client->active->expiry > cur_time) {
1412 piaddr(ip->client->active->address));
1416 ip->client->active->medium);
1417 script_write_params("new_", ip->client->active);
1418 if (ip->client->alias)
1420 ip->client->alias);
1427 ip->client->active->renewal) {
1428 ip->client->state = S_BOUND;
1430 (int)(ip->client->active->renewal -
1433 ip->client->active->renewal,
1436 ip->client->state = S_BOUND;
1447 if (!ip->client->leases) {
1448 ip->client->leases = ip->client->active;
1449 ip->client->active = NULL;
1456 for (lp = ip->client->leases; lp->next; lp = lp->next)
1458 lp->next = ip->client->active;
1459 if (lp->next)
1460 lp->next->next = NULL;
1461 ip->client->active = ip->client->leases;
1462 ip->client->leases = ip->client->leases->next;
1467 if (ip->client->active == loop)
1470 loop = ip->client->active;
1476 note("No working leases in persistent database - sleeping.\n");
1478 if (ip->client->alias)
1479 script_write_params("alias_", ip->client->alias);
1481 ip->client->state = S_INIT;
1482 add_timeout(cur_time + ip->client->config->retry_interval, state_init,
1495 interval = cur_time - ip->client->first_sending;
1497 /* If we're in the INIT-REBOOT or REQUESTING state and we're
1500 /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1501 means either that we're on a network with no DHCP server,
1505 reused our old address. In the former case, we're hosed
1506 anyway. This is not a win-prone situation. */
1507 if ((ip->client->state == S_REBOOTING ||
1508 ip->client->state == S_REQUESTING) &&
1509 interval > ip->client->config->reboot_timeout) {
1511 ip->client->state = S_INIT;
1517 /* If we're in the reboot state, make sure the media is set up
1519 if (ip->client->state == S_REBOOTING &&
1520 !ip->client->medium &&
1521 ip->client->active->medium ) {
1522 script_init("MEDIUM", ip->client->active->medium);
1529 ip->client->medium = ip->client->active->medium;
1534 if (ip->client->state != S_REQUESTING &&
1535 cur_time > ip->client->active->expiry) {
1538 script_write_params("old_", ip->client->active);
1539 if (ip->client->alias)
1540 script_write_params("alias_", ip->client->alias);
1546 if (ip->client->alias)
1547 script_write_params("alias_", ip->client->alias);
1550 ip->client->state = S_INIT;
1556 if (!ip->client->interval)
1557 ip->client->interval = ip->client->config->initial_interval;
1559 ip->client->interval += ((arc4random() >> 2) %
1560 (2 * ip->client->interval));
1563 if (ip->client->interval >
1564 ip->client->config->backoff_cutoff)
1565 ip->client->interval =
1566 ((ip->client->config->backoff_cutoff / 2) +
1567 ((arc4random() >> 2) % ip->client->interval));
1571 if (ip->client->state != S_REQUESTING &&
1572 cur_time + ip->client->interval >
1573 ip->client->active->expiry)
1574 ip->client->interval =
1575 ip->client->active->expiry - cur_time + 1;
1577 /* If the lease T2 time has elapsed, or if we're not yet bound,
1579 if (ip->client->state == S_REQUESTING ||
1580 ip->client->state == S_REBOOTING ||
1581 cur_time > ip->client->active->rebind)
1584 memcpy(&to.s_addr, ip->client->destination.iabuf,
1587 if (ip->client->state != S_REQUESTING &&
1588 ip->client->state != S_REBOOTING)
1589 memcpy(&from, ip->client->active->address.iabuf,
1595 if (ip->client->state == S_REQUESTING)
1596 ip->client->packet.secs = ip->client->secs;
1599 ip->client->packet.secs = htons(interval);
1601 ip->client->packet.secs = htons(65535);
1604 note("DHCPREQUEST on %s to %s port %d", ip->name, inet_ntoa(to),
1608 send_packet_unpriv(privfd, &ip->client->packet,
1609 ip->client->packet_length, from, to);
1611 add_timeout(cur_time + ip->client->interval, send_request, ip);
1619 note("DHCPDECLINE on %s to %s port %d", ip->name,
1623 send_packet_unpriv(privfd, &ip->client->packet,
1624 ip->client->packet_length, inaddr_any, inaddr_broadcast);
1637 memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1642 options[i]->value = &discover;
1643 options[i]->len = sizeof(discover);
1644 options[i]->buf_size = sizeof(discover);
1645 options[i]->timeout = 0xFFFFFFFF;
1650 options[i]->value = ip->client->config->requested_options;
1651 options[i]->len = ip->client->config->requested_option_count;
1652 options[i]->buf_size =
1653 ip->client->config->requested_option_count;
1654 options[i]->timeout = 0xFFFFFFFF;
1658 ip->client->requested_address = lease->address;
1661 options[i]->value = lease->address.iabuf;
1662 options[i]->len = lease->address.len;
1663 options[i]->buf_size = lease->address.len;
1664 options[i]->timeout = 0xFFFFFFFF;
1666 ip->client->requested_address.len = 0;
1668 /* Send any options requested in the config file. */
1671 ip->client->config->send_options[i].data) {
1673 options[i]->value =
1674 ip->client->config->send_options[i].data;
1675 options[i]->len =
1676 ip->client->config->send_options[i].len;
1677 options[i]->buf_size =
1678 ip->client->config->send_options[i].len;
1679 options[i]->timeout = 0xFFFFFFFF;
1682 /* send host name if not set via config file. */
1688 len = posDot - hostname;
1692 options[DHO_HOST_NAME]->value = hostname;
1693 options[DHO_HOST_NAME]->len = len;
1694 options[DHO_HOST_NAME]->buf_size = len;
1695 options[DHO_HOST_NAME]->timeout = 0xFFFFFFFF;
1700 char client_ident[sizeof(ip->hw_address.haddr) + 1];
1702 int hwlen = (ip->hw_address.hlen < sizeof(client_ident)-1) ?
1703 ip->hw_address.hlen : sizeof(client_ident)-1;
1704 client_ident[0] = ip->hw_address.htype;
1705 memcpy(&client_ident[1], ip->hw_address.haddr, hwlen);
1707 options[DHO_DHCP_CLIENT_IDENTIFIER]->value = client_ident;
1708 options[DHO_DHCP_CLIENT_IDENTIFIER]->len = hwlen+1;
1709 options[DHO_DHCP_CLIENT_IDENTIFIER]->buf_size = hwlen+1;
1710 options[DHO_DHCP_CLIENT_IDENTIFIER]->timeout = 0xFFFFFFFF;
1714 ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1716 if (ip->client->packet_length < BOOTP_MIN_LEN)
1717 ip->client->packet_length = BOOTP_MIN_LEN;
1719 ip->client->packet.op = BOOTREQUEST;
1720 ip->client->packet.htype = ip->hw_address.htype;
1721 ip->client->packet.hlen = ip->hw_address.hlen;
1722 ip->client->packet.hops = 0;
1723 ip->client->packet.xid = arc4random();
1724 ip->client->packet.secs = 0; /* filled in by send_discover. */
1725 ip->client->packet.flags = 0;
1727 memset(&(ip->client->packet.ciaddr),
1728 0, sizeof(ip->client->packet.ciaddr));
1729 memset(&(ip->client->packet.yiaddr),
1730 0, sizeof(ip->client->packet.yiaddr));
1731 memset(&(ip->client->packet.siaddr),
1732 0, sizeof(ip->client->packet.siaddr));
1733 memset(&(ip->client->packet.giaddr),
1734 0, sizeof(ip->client->packet.giaddr));
1735 memcpy(ip->client->packet.chaddr,
1736 ip->hw_address.haddr, ip->hw_address.hlen);
1749 memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1754 options[i]->value = &request;
1755 options[i]->len = sizeof(request);
1756 options[i]->buf_size = sizeof(request);
1757 options[i]->timeout = 0xFFFFFFFF;
1762 options[i]->value = ip->client->config->requested_options;
1763 options[i]->len = ip->client->config->requested_option_count;
1764 options[i]->buf_size =
1765 ip->client->config->requested_option_count;
1766 options[i]->timeout = 0xFFFFFFFF;
1770 if (ip->client->state == S_REQUESTING) {
1774 options[i]->value = lease->options[i].data;
1775 options[i]->len = lease->options[i].len;
1776 options[i]->buf_size = lease->options[i].len;
1777 options[i]->timeout = 0xFFFFFFFF;
1779 if (ip->client->state == S_REQUESTING ||
1780 ip->client->state == S_REBOOTING) {
1781 ip->client->requested_address = lease->address;
1784 options[i]->value = lease->address.iabuf;
1785 options[i]->len = lease->address.len;
1786 options[i]->buf_size = lease->address.len;
1787 options[i]->timeout = 0xFFFFFFFF;
1789 ip->client->requested_address.len = 0;
1791 /* Send any options requested in the config file. */
1794 ip->client->config->send_options[i].data) {
1796 options[i]->value =
1797 ip->client->config->send_options[i].data;
1798 options[i]->len =
1799 ip->client->config->send_options[i].len;
1800 options[i]->buf_size =
1801 ip->client->config->send_options[i].len;
1802 options[i]->timeout = 0xFFFFFFFF;
1805 /* send host name if not set via config file. */
1811 len = posDot - hostname;
1815 options[DHO_HOST_NAME]->value = hostname;
1816 options[DHO_HOST_NAME]->len = len;
1817 options[DHO_HOST_NAME]->buf_size = len;
1818 options[DHO_HOST_NAME]->timeout = 0xFFFFFFFF;
1823 char client_ident[sizeof(ip->hw_address.haddr) + 1];
1825 int hwlen = (ip->hw_address.hlen < sizeof(client_ident)-1) ?
1826 ip->hw_address.hlen : sizeof(client_ident)-1;
1827 client_ident[0] = ip->hw_address.htype;
1828 memcpy(&client_ident[1], ip->hw_address.haddr, hwlen);
1830 options[DHO_DHCP_CLIENT_IDENTIFIER]->value = client_ident;
1831 options[DHO_DHCP_CLIENT_IDENTIFIER]->len = hwlen+1;
1832 options[DHO_DHCP_CLIENT_IDENTIFIER]->buf_size = hwlen+1;
1833 options[DHO_DHCP_CLIENT_IDENTIFIER]->timeout = 0xFFFFFFFF;
1837 ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1839 if (ip->client->packet_length < BOOTP_MIN_LEN)
1840 ip->client->packet_length = BOOTP_MIN_LEN;
1842 ip->client->packet.op = BOOTREQUEST;
1843 ip->client->packet.htype = ip->hw_address.htype;
1844 ip->client->packet.hlen = ip->hw_address.hlen;
1845 ip->client->packet.hops = 0;
1846 ip->client->packet.xid = ip->client->xid;
1847 ip->client->packet.secs = 0; /* Filled in by send_request. */
1849 /* If we own the address we're requesting, put it in ciaddr;
1851 if (ip->client->state == S_BOUND ||
1852 ip->client->state == S_RENEWING ||
1853 ip->client->state == S_REBINDING) {
1854 memcpy(&ip->client->packet.ciaddr,
1855 lease->address.iabuf, lease->address.len);
1856 ip->client->packet.flags = 0;
1858 memset(&ip->client->packet.ciaddr, 0,
1859 sizeof(ip->client->packet.ciaddr));
1860 ip->client->packet.flags = 0;
1863 memset(&ip->client->packet.yiaddr, 0,
1864 sizeof(ip->client->packet.yiaddr));
1865 memset(&ip->client->packet.siaddr, 0,
1866 sizeof(ip->client->packet.siaddr));
1867 memset(&ip->client->packet.giaddr, 0,
1868 sizeof(ip->client->packet.giaddr));
1869 memcpy(ip->client->packet.chaddr,
1870 ip->hw_address.haddr, ip->hw_address.hlen);
1883 memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1888 options[i]->value = &decline;
1889 options[i]->len = sizeof(decline);
1890 options[i]->buf_size = sizeof(decline);
1891 options[i]->timeout = 0xFFFFFFFF;
1896 options[i]->value = lease->options[i].data;
1897 options[i]->len = lease->options[i].len;
1898 options[i]->buf_size = lease->options[i].len;
1899 options[i]->timeout = 0xFFFFFFFF;
1901 /* Send back the address we're declining. */
1904 options[i]->value = lease->address.iabuf;
1905 options[i]->len = lease->address.len;
1906 options[i]->buf_size = lease->address.len;
1907 options[i]->timeout = 0xFFFFFFFF;
1911 if (ip->client->config->send_options[i].len) {
1913 options[i]->value = ip->client->config->send_options[i].data;
1914 options[i]->len = ip->client->config->send_options[i].len;
1915 options[i]->buf_size = ip->client->config->send_options[i].len;
1916 options[i]->timeout = 0xFFFFFFFF;
1921 ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1923 if (ip->client->packet_length < BOOTP_MIN_LEN)
1924 ip->client->packet_length = BOOTP_MIN_LEN;
1926 ip->client->packet.op = BOOTREQUEST;
1927 ip->client->packet.htype = ip->hw_address.htype;
1928 ip->client->packet.hlen = ip->hw_address.hlen;
1929 ip->client->packet.hops = 0;
1930 ip->client->packet.xid = ip->client->xid;
1931 ip->client->packet.secs = 0; /* Filled in by send_request. */
1932 ip->client->packet.flags = 0;
1935 memset(&ip->client->packet.ciaddr, 0,
1936 sizeof(ip->client->packet.ciaddr));
1937 memset(&ip->client->packet.yiaddr, 0,
1938 sizeof(ip->client->packet.yiaddr));
1939 memset(&ip->client->packet.siaddr, 0,
1940 sizeof(ip->client->packet.siaddr));
1941 memset(&ip->client->packet.giaddr, 0,
1942 sizeof(ip->client->packet.giaddr));
1943 memcpy(ip->client->packet.chaddr,
1944 ip->hw_address.haddr, ip->hw_address.hlen);
1952 if (lease->server_name)
1953 free(lease->server_name);
1954 if (lease->filename)
1955 free(lease->filename);
1957 if (lease->options[i].len)
1958 free(lease->options[i].data);
1988 for (lp = ifi->client->leases; lp; lp = lp->next)
1990 if (ifi->client->active)
1991 write_client_lease(ifi, ifi->client->active, 1);
2013 /* If the lease came from the config file, we don't need to stash
2015 if (lease->is_static)
2025 if (lease->is_bootp)
2027 fprintf(leaseFile, " interface \"%s\";\n", ip->name);
2028 fprintf(leaseFile, " fixed-address %s;\n", piaddr(lease->address));
2029 if (lease->nextserver.len == sizeof(inaddr_any) &&
2030 0 != memcmp(lease->nextserver.iabuf, &inaddr_any,
2032 fprintf(leaseFile, " next-server %s;\n",
2033 piaddr(lease->nextserver));
2034 if (lease->filename)
2035 fprintf(leaseFile, " filename \"%s\";\n", lease->filename);
2036 if (lease->server_name)
2037 fprintf(leaseFile, " server-name \"%s\";\n",
2038 lease->server_name);
2039 if (lease->medium)
2040 fprintf(leaseFile, " medium \"%s\";\n", lease->medium->string);
2042 if (lease->options[i].len)
2045 pretty_print_option(i, lease->options[i].data,
2046 lease->options[i].len, 1, 1));
2048 t = gmtime(&lease->renewal);
2050 t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
2051 t->tm_hour, t->tm_min, t->tm_sec);
2052 t = gmtime(&lease->rebind);
2054 t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
2055 t->tm_hour, t->tm_min, t->tm_sec);
2056 t = gmtime(&lease->expiry);
2058 t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
2059 t->tm_hour, t->tm_min, t->tm_sec);
2072 if (medium != NULL && medium->string != NULL)
2073 mediumlen = strlen(medium->string);
2087 errs += buf_add(buf, medium->string, mediumlen);
2095 if (buf_close(privfd, buf) == -1)
2105 ip->client->scriptEnvsize = 100;
2106 if (ip->client->scriptEnv == NULL)
2107 ip->client->scriptEnv =
2108 malloc(ip->client->scriptEnvsize * sizeof(char *));
2109 if (ip->client->scriptEnv == NULL)
2112 ip->client->scriptEnv[0] = strdup(CLIENT_PATH);
2113 if (ip->client->scriptEnv[0] == NULL)
2116 ip->client->scriptEnv[1] = NULL;
2118 script_set_env(ip->client, "", "interface", ip->name);
2121 script_set_env(ip->client, "", "medium", medium);
2123 script_set_env(ip->client, "", "reason", reason);
2136 script_set_env(ip->client, prefix, "ip_address",
2137 piaddr(lease->address));
2139 if (ip->client->config->default_actions[DHO_SUBNET_MASK] ==
2141 dp = ip->client->config->defaults[DHO_SUBNET_MASK].data;
2142 len = ip->client->config->defaults[DHO_SUBNET_MASK].len;
2144 dp = lease->options[DHO_SUBNET_MASK].data;
2145 len = lease->options[DHO_SUBNET_MASK].len;
2147 if (len && (len < sizeof(lease->address.iabuf))) {
2152 subnet = subnet_number(lease->address, netmask);
2154 script_set_env(ip->client, prefix, "network_number",
2156 if (!lease->options[DHO_BROADCAST_ADDRESS].len) {
2159 script_set_env(ip->client, prefix,
2166 if (lease->filename)
2167 script_set_env(ip->client, prefix, "filename", lease->filename);
2168 if (lease->server_name)
2169 script_set_env(ip->client, prefix, "server_name",
2170 lease->server_name);
2174 if (ip->client->config->defaults[i].len) {
2175 if (lease->options[i].len) {
2177 ip->client->config->default_actions[i]) {
2179 dp = lease->options[i].data;
2180 len = lease->options[i].len;
2184 dp = ip->client->
2185 config->defaults[i].data;
2186 len = ip->client->
2187 config->defaults[i].len;
2190 len = ip->client->
2191 config->defaults[i].len +
2192 lease->options[i].len;
2201 ip->client->
2202 config->defaults[i].data,
2203 ip->client->
2204 config->defaults[i].len);
2205 memcpy(dp + ip->client->
2206 config->defaults[i].len,
2207 lease->options[i].data,
2208 lease->options[i].len);
2213 * When we append, we assume that we're
2218 len = ip->client->
2219 config->defaults[i].len +
2220 lease->options[i].len;
2228 lease->options[i].data,
2229 lease->options[i].len);
2230 for (dp = dbuf + lease->options[i].len;
2231 dp > dbuf; dp--, len--)
2232 if (dp[-1] != '\0')
2235 ip->client->
2236 config->defaults[i].data,
2237 ip->client->
2238 config->defaults[i].len);
2243 dp = ip->client->
2244 config->defaults[i].data;
2245 len = ip->client->
2246 config->defaults[i].len;
2248 } else if (lease->options[i].len) {
2249 len = lease->options[i].len;
2250 dp = lease->options[i].data;
2259 script_set_env(ip->client, prefix, name,
2263 snprintf(tbuf, sizeof(tbuf), "%d", (int)lease->expiry);
2264 script_set_env(ip->client, prefix, "expiry", tbuf);
2275 if (lease->filename != NULL)
2276 fn_len = strlen(lease->filename);
2277 if (lease->server_name != NULL)
2278 sn_len = strlen(lease->server_name);
2288 hdr.len += sizeof(lease->options[i].len);
2289 hdr.len += lease->options[i].len;
2301 errs += buf_add(buf, lease->filename, fn_len);
2303 errs += buf_add(buf, lease->server_name, sn_len);
2308 errs += buf_add(buf, &lease->options[i].len,
2309 sizeof(lease->options[i].len));
2310 errs += buf_add(buf, lease->options[i].data,
2311 lease->options[i].len);
2317 if (buf_close(privfd, buf) == -1)
2337 if (buf_close(privfd, buf) == -1)
2364 scriptName = ip->client->config->script_name;
2365 envp = ip->client->scriptEnv;
2395 script_flush_env(ip->client);
2421 for (i = 0; client->scriptEnv[i]; i++)
2422 if (strncmp(client->scriptEnv[i], name, namelen) == 0 &&
2423 client->scriptEnv[i][namelen] == '=')
2426 if (client->scriptEnv[i])
2428 free(client->scriptEnv[i]);
2431 if (i >= client->scriptEnvsize - 1) {
2433 int newscriptEnvsize = client->scriptEnvsize + 50;
2435 newscriptEnv = realloc(client->scriptEnv,
2438 free(client->scriptEnv);
2439 client->scriptEnv = NULL;
2440 client->scriptEnvsize = 0;
2443 client->scriptEnv = newscriptEnv;
2444 client->scriptEnvsize = newscriptEnvsize;
2448 client->scriptEnv[i + 1] = NULL;
2451 client->scriptEnv[i] = malloc(strlen(prefix) + strlen(name) + 1 +
2453 if (client->scriptEnv[i] == NULL)
2455 snprintf(client->scriptEnv[i], strlen(prefix) + strlen(name) +
2464 for (i = 0; client->scriptEnv[i]; i++) {
2465 free(client->scriptEnv[i]);
2466 client->scriptEnv[i] = NULL;
2468 client->scriptEnvsize = 0;
2476 for (i = 0; option->name[i]; i++) {
2479 if (option->name[i] == '-')
2482 buf[i] = option->name[i];
2503 if (daemonfd(-1, nullfd) == -1)
2515 if (nullfd != -1) {
2517 nullfd = -1;
2535 /* we use this, since this is what gets passed to dhclient-script */
2537 opbuf = pretty_print_option(option, l->options[option].data,
2538 l->options[option].len, 0, 0);
2540 sbuf = option_as_string(option, l->options[option].data,
2541 l->options[option].len);
2584 l->options[option].len = 0;
2585 free(l->options[option].data);
2594 l->options[option].len = 0;
2595 free(l->options[option].data);
2649 return (check_classless_option(l->options[option].data,
2650 l->options[option].len));
2696 mask = (in_addr_t)(~0) << (32 - width);
2709 data[i - 1] = (unsigned char)(
2710 (addr >> (((32 - width)/8)*8)) & 0xFF);
2752 /* 256 char limit re resolv.conf(5) */
2786 /* 6 domain limit re resolv.conf(5) */
2831 opleft -= 4;
2837 opleft -= 2;
2840 opleft--;
2859 case -1:
2867 setproctitle("%s [priv]", ifi->name);
2875 close(ifi->rfdesc);
2876 ifi->rfdesc = -1;
2881 if ((nfds = poll(pfd, 1, INFTIM)) == -1)