36 #include <dns/result.h>
52 extern int asprintf(
char **strp,
const char *fmt, ...);
87 #define ASSERT_STATE(state_is, state_shouldbe) {}
90 static const char copyright[] =
"Copyright 2004-2019 Internet Systems Consortium.";
91 static const char arr [] =
"All rights reserved.";
92 static const char message [] =
"Internet Systems Consortium DHCP Client";
93 static const char url [] =
"For info, please visit https://www.isc.org/software/dhcp/";
98 #if defined(DHCPv6) && defined(DHCP4o6)
99 int dhcp4o6_state = -1;
116 int dad_wait_time = 0;
117 int prefix_len_hint = 0;
131 static isc_result_t write_duid(
struct data_string *duid);
134 static int check_domain_name(
const char *ptr,
size_t len,
int dots);
135 static int check_domain_name_list(
const char *ptr,
size_t len,
int dots);
137 const char *ptr,
size_t len);
139 #if defined(NSUPDATE)
161 #if defined(DHCPv6) && defined(DHCP4o6)
162 static void dhcp4o6_poll(
void *dummy);
163 static void dhcp4o6_resume(
void);
164 static void recv_dhcpv4_response(
struct data_string *raw);
165 static int send_dhcpv4_query(
struct client_state *client,
int broadcast);
167 static void dhcp4o6_stop(
void);
168 static void forw_dhcpv4_response(
struct packet *
packet);
169 static void forw_dhcpv4_query(
struct data_string *raw);
176 static const char use_noarg[] =
"No argument for command: %s";
178 static const char use_v6command[] =
"Command not used for DHCPv4: %s";
183 #define DHCLIENT_USAGE0 \
184 "[-4|-6] [-SNTPRI1dvrxi] [-nw] -4o6 <port>] [-p <port>] [-D LL|LLT]\n" \
185 " [--dad-wait-time <seconds>] [--prefix-len-hint <length>]\n" \
186 " [--decline-wait-time <seconds>]\n" \
187 " [--address-prefix-len <length>]\n"
189 #define DHCLIENT_USAGE0 \
190 "[-4|-6] [-SNTPRI1dvrxi] [-nw] [-p <port>] [-D LL|LLT]\n" \
191 " [--dad-wait-time <seconds>] [--prefix-len-hint <length>]\n" \
192 " [--decline-wait-time <seconds>]\n" \
193 " [--address-prefix-len <length>]\n"
196 #define DHCLIENT_USAGE0 \
197 "[-I1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n" \
198 " [--decline-wait-time <seconds>]\n"
201 #define DHCLIENT_USAGEC \
202 " [-s server-addr] [-cf config-file]\n" \
203 " [-df duid-file] [-lf lease-file]\n" \
204 " [-pf pid-file] [--no-pid] [-e VAR=val]\n" \
205 " [-sf script-file] [interface]*\n" \
206 " [-C <dhcp-client-identifier>] [-B]\n" \
207 " [-H <host-name> | -F <fqdn.fqdn>] [--timeout <timeout>]\n" \
208 " [-V <vendor-class-identifier>]\n" \
209 " [--request-options <request option list>]"
211 #define DHCLIENT_USAGEH "{--version|--help|-h}"
216 usage(
const char *sfmt,
const char *sarg)
224 #ifdef PRINT_SPECIFIC_CL_ERRORS
249 int release_mode = 0;
254 int no_dhclient_conf = 0;
255 int no_dhclient_db = 0;
256 int no_dhclient_pid = 0;
257 int no_dhclient_script = 0;
259 int local_family_set = 0;
261 u_int16_t dhcp4o6_port = 0;
271 char *dhcp_client_identifier_arg = NULL;
272 char *dhcp_host_name_arg = NULL;
273 char *dhcp_fqdn_arg = NULL;
274 char *dhcp_vendor_class_identifier_arg = NULL;
275 char *dhclient_request_options = NULL;
278 char *arg_conf = NULL;
279 int arg_conf_len = 0;
280 #ifdef HAVE_LIBCAP_NG
281 int keep_capabilities = 0;
290 fd = open(
"/dev/null", O_RDWR | O_CLOEXEC);
292 fd = open(
"/dev/null", O_RDWR | O_CLOEXEC);
294 fd = open(
"/dev/null", O_RDWR | O_CLOEXEC);
302 #if !(defined(DEBUG) || defined(__CYGWIN32__))
303 setlogmask(LOG_UPTO(LOG_INFO));
307 for (i = 1; i < argc; i++) {
308 if (!strcmp(argv[i],
"-r")) {
310 }
else if (!strcmp(argv[i],
"-x")) {
312 }
else if (!strcmp(argv[i],
"-d")) {
314 }
else if (!strcmp(argv[i],
"--version")) {
315 const char vstring[] =
"isc-dhclient-";
323 }
else if (!strcmp(argv[i],
"--help") ||
324 !strcmp(argv[i],
"-h")) {
325 const char *pname = isc_file_basename(
progname);
349 if ((pid = fork ()) < 0)
355 (void) close(
dfd[1]);
359 n = read(
dfd[0], &buf, 1);
362 }
while (n == -1 && errno == EINTR);
366 (void) close(
dfd[0]);
373 log_fatal(
"Can't initialize context: %s",
374 isc_result_totext(status));
380 isc_result_totext(status));
390 for (i = 1; i < argc; i++) {
391 if (!strcmp(argv[i],
"-r")) {
395 }
else if (!strcmp(argv[i],
"-4")) {
397 log_fatal(
"Client can only do v4 or v6, not "
399 local_family_set = 1;
401 }
else if (!strcmp(argv[i],
"-6")) {
403 log_fatal(
"Client can only do v4 or v6, not "
405 local_family_set = 1;
408 }
else if (!strcmp(argv[i],
"-4o6")) {
410 usage(use_noarg, argv[i-1]);
413 log_debug(
"DHCPv4 over DHCPv6 over ::1 port %d and %d",
415 ntohs(dhcp4o6_port) + 1);
419 }
else if (!strcmp(argv[i],
"-x")) {
423 }
else if (!strcmp(argv[i],
"-p")) {
425 usage(use_noarg, argv[i-1]);
427 log_debug(
"binding to user-specified port %d",
429 }
else if (!strcmp(argv[i],
"-d")) {
432 }
else if (!strcmp(argv[i],
"-pf")) {
434 usage(use_noarg, argv[i-1]);
437 }
else if (!strcmp(argv[i],
"--no-pid")) {
439 }
else if (!strcmp(argv[i],
"-cf")) {
441 usage(use_noarg, argv[i-1]);
443 no_dhclient_conf = 1;
444 }
else if (!strcmp(argv[i],
"-df")) {
446 usage(use_noarg, argv[i-1]);
448 }
else if (!strcmp(argv[i],
"-lf")) {
450 usage(use_noarg, argv[i-1]);
453 }
else if (!strcmp(argv[i],
"-sf")) {
455 usage(use_noarg, argv[i-1]);
457 no_dhclient_script = 1;
458 }
else if (!strcmp(argv[i],
"-1")) {
460 }
else if (!strcmp(argv[i],
"-q")) {
462 }
else if (!strcmp(argv[i],
"-s")) {
464 usage(use_noarg, argv[i-1]);
466 }
else if (!strcmp(argv[i],
"-g")) {
468 usage(use_noarg, argv[i-1]);
470 }
else if (!strcmp(argv[i],
"-nw")) {
472 }
else if (!strcmp(argv[i],
"-n")) {
475 }
else if (!strcmp(argv[i],
"-w")) {
478 }
else if (!strcmp(argv[i],
"-e")) {
481 usage(use_noarg, argv[i-1]);
482 tmp =
dmalloc(strlen(argv[i]) +
sizeof *tmp,
MDL);
485 strcpy(tmp->
string, argv[i]);
490 }
else if (!strcmp(argv[i],
"-S")) {
492 usage(use_v6command, argv[i]);
494 local_family_set = 1;
498 }
else if (!strcmp(argv[i],
"-N")) {
500 usage(use_v6command, argv[i]);
502 local_family_set = 1;
508 }
else if (!strcmp(argv[i],
"-T")) {
510 usage(use_v6command, argv[i]);
512 local_family_set = 1;
518 }
else if (!strcmp(argv[i],
"-P")) {
520 usage(use_v6command, argv[i]);
522 local_family_set = 1;
528 }
else if (!strcmp(argv[i],
"-R")) {
530 usage(use_v6command, argv[i]);
532 local_family_set = 1;
535 }
else if (!strcmp(argv[i],
"--dad-wait-time")) {
537 usage(use_noarg, argv[i-1]);
540 dad_wait_time = (
int)strtol(argv[i], &s, 10);
541 if (errno || (*s !=
'\0') || (dad_wait_time < 0)) {
542 usage(
"Invalid value for --dad-wait-time: %s",
545 }
else if (!strcmp(argv[i],
"--prefix-len-hint")) {
547 usage(use_noarg, argv[i-1]);
551 prefix_len_hint = (
int)strtol(argv[i], &s, 10);
552 if (errno || (*s !=
'\0') || (prefix_len_hint < 0)) {
553 usage(
"Invalid value for --prefix-len-hint: %s",
556 }
else if (!strcmp(argv[i],
"--address-prefix-len")) {
558 usage(use_noarg, argv[i-1]);
562 if (errno || (*s !=
'\0') ||
564 usage(
"Invalid value for"
565 " --address-prefix-len: %s", argv[i]);
568 }
else if (!strcmp(argv[i],
"--decline-wait-time")) {
570 usage(use_noarg, argv[i-1]);
575 if (errno || (*s !=
'\0') ||
577 usage(
"Invalid value for "
578 "--decline-wait-time: %s", argv[i]);
580 }
else if (!strcmp(argv[i],
"-D")) {
583 usage(use_noarg, argv[i-1]);
584 if (!strcasecmp(argv[i],
"LL")) {
586 }
else if (!strcasecmp(argv[i],
"LLT")) {
589 usage(
"Unknown argument to -D: %s", argv[i]);
591 }
else if (!strcmp(argv[i],
"-i")) {
594 }
else if (!strcmp(argv[i],
"-I")) {
597 }
else if (!strcmp(argv[i],
"-v")) {
599 }
else if (!strcmp(argv[i],
"-C")) {
600 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
601 usage(use_noarg, argv[i-1]);
610 dhcp_client_identifier_arg = argv[i];
611 }
else if (!strcmp(argv[i],
"-B")) {
613 }
else if (!strcmp(argv[i],
"-H")) {
614 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
615 usage(use_noarg, argv[i-1]);
624 if (dhcp_host_name_arg != NULL) {
625 log_error(
"The -H <host-name> and -F <fqdn> arguments are mutually exclusive");
629 dhcp_host_name_arg = argv[i];
630 }
else if (!strcmp(argv[i],
"-F")) {
631 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
632 usage(use_noarg, argv[i-1]);
641 if (dhcp_fqdn_arg != NULL) {
642 log_error(
"Only one -F <fqdn> argument can be specified");
646 if (dhcp_host_name_arg != NULL) {
647 log_error(
"The -F <fqdn> and -H <host-name> arguments are mutually exclusive");
651 dhcp_fqdn_arg = argv[i];
652 }
else if (!strcmp(argv[i],
"--timeout")) {
653 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
654 usage(use_noarg, argv[i-1]);
658 if ((timeout_arg = atoi(argv[i])) <= 0) {
659 log_error(
"timeout option must be > 0 - bad value: %s",argv[i]);
662 }
else if (!strcmp(argv[i],
"-V")) {
663 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
664 usage(use_noarg, argv[i-1]);
673 dhcp_vendor_class_identifier_arg = argv[i];
674 }
else if (!strcmp(argv[i],
"--request-options")) {
675 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
676 usage(use_noarg, argv[i-1]);
680 dhclient_request_options = argv[i];
682 }
else if (!strcmp(argv[i],
"-nc")) {
683 #ifdef HAVE_LIBCAP_NG
684 keep_capabilities = 1;
686 }
else if (argv[i][0] ==
'-') {
687 usage(
"Unknown command: %s", argv[i]);
689 usage(
"No interfaces comamnd -n and "
690 " requested interface %s", argv[i]);
694 status = interface_allocate(&tmp,
MDL);
696 log_fatal(
"Can't record interface %s:%s",
697 argv[i], isc_result_totext(status));
698 if (strlen(argv[i]) >=
sizeof(tmp->
name))
699 log_fatal(
"%s: interface name too long (is %ld)",
700 argv[i], (
long)strlen(argv[i]));
701 strcpy(tmp->
name, argv[i]);
703 interface_reference(&tmp->
next,
719 usage(
"PD %s only supports one requested interface",
"-P");
722 #if defined(DHCPv6) && defined(DHCP4o6)
724 (exit_mode || release_mode))
725 log_error(
"Can't relay DHCPv4-over-DHCPv6 "
726 "without a persistent DHCPv6 client");
729 log_fatal(
"DHCPv4-over-DHCPv6 requires an explicit "
730 "interface on which to be applied");
733 if (!no_dhclient_conf && (s = getenv(
"PATH_DHCLIENT_CONF"))) {
736 if (!no_dhclient_db && (s = getenv(
"PATH_DHCLIENT_DB"))) {
739 if (!no_dhclient_pid && (s = getenv(
"PATH_DHCLIENT_PID"))) {
742 if (!no_dhclient_script && (s = getenv(
"PATH_DHCLIENT_SCRIPT"))) {
746 #ifdef HAVE_LIBCAP_NG
748 if (!keep_capabilities) {
749 capng_clear(CAPNG_SELECT_CAPS);
750 capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
752 capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
753 CAP_NET_ADMIN, CAP_NET_RAW,
754 CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1);
755 capng_apply(CAPNG_SELECT_CAPS);
800 e = fscanf(pidfd,
"%ld\n", &temp);
801 oldpid = (pid_t)temp;
803 if (e != 0 && e != EOF && oldpid) {
804 if (kill(oldpid, SIGTERM) == 0) {
805 log_info(
"Killed old client process");
815 }
else if (errno == ESRCH) {
829 char *new_path_dhclient_pid;
848 int n_len = strlen(
ip->name);
850 new_path_dhclient_pid = (
char*) malloc(pfx + n_len + 6);
852 sprintf(new_path_dhclient_pid + pfx,
"-%s.pid",
ip->name);
854 if ((pidfd = fopen(new_path_dhclient_pid,
"re")) != NULL) {
855 e = fscanf(pidfd,
"%ld\n", &temp);
856 oldpid = (pid_t)temp;
858 if (e != 0 && e != EOF) {
860 if (kill(oldpid, SIGTERM) == 0)
868 free(new_path_dhclient_pid);
877 char procfn[256] =
"";
880 if ((fscanf(pidfp,
"%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
881 snprintf(procfn,256,
"/proc/%u",dhcpid);
882 dhc_running = (access(procfn, F_OK) == 0);
889 log_fatal(
"dhclient(%u) is already running - exiting. ", dhcpid);
914 memcpy(&
giaddr, he->h_addr_list[0],
923 gettimeofday(&
cur_tv, NULL);
930 he = gethostbyname(server);
956 usage(
"Stateless command: %s incompatibile with "
957 "other commands",
"-S");
959 #if defined(DHCPv6) && defined(DHCP4o6)
968 if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg !=
'\0')) {
969 arg_conf_len =
asprintf(&arg_conf,
"send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);
971 if ((arg_conf == 0) || (arg_conf_len <= 0))
972 log_fatal(
"Unable to send -C option dhcp-client-identifier");
975 if ((dhcp_host_name_arg != NULL) && (*dhcp_host_name_arg !=
'\0')) {
977 arg_conf_len =
asprintf(&arg_conf,
"send host-name \"%s\";", dhcp_host_name_arg);
979 if ((arg_conf == 0) || (arg_conf_len <= 0))
980 log_fatal(
"Unable to send -H option host-name");
982 char *last_arg_conf = arg_conf;
984 arg_conf_len =
asprintf(&arg_conf,
"%s\nsend host-name \"%s\";", last_arg_conf, dhcp_host_name_arg);
986 if ((arg_conf == 0) || (arg_conf_len <= 0))
987 log_fatal(
"Unable to send -H option host-name");
993 if ((dhcp_fqdn_arg != NULL) && (*dhcp_fqdn_arg !=
'\0')) {
995 arg_conf_len =
asprintf(&arg_conf,
"send fqdn.fqdn \"%s\";", dhcp_fqdn_arg);
997 if ((arg_conf == 0) || (arg_conf_len <= 0))
998 log_fatal(
"Unable to send -F option fqdn.fqdn");
1000 char *last_arg_conf = arg_conf;
1002 arg_conf_len =
asprintf(&arg_conf,
"%s\nsend fqdn.fqdn \"%s\";", last_arg_conf, dhcp_fqdn_arg);
1004 if ((arg_conf == 0) || (arg_conf_len <= 0))
1005 log_fatal(
"Unable to send -F option fqdn.fqdn");
1007 free(last_arg_conf);
1012 if (arg_conf == 0) {
1013 arg_conf_len =
asprintf(&arg_conf,
"timeout %d;", timeout_arg);
1015 if ((arg_conf == 0) || (arg_conf_len <= 0))
1016 log_fatal(
"Unable to process --timeout timeout argument");
1018 char *last_arg_conf = arg_conf;
1020 arg_conf_len =
asprintf(&arg_conf,
"%s\ntimeout %d;", last_arg_conf, timeout_arg);
1022 if ((arg_conf == 0) || (arg_conf_len == 0))
1023 log_fatal(
"Unable to process --timeout timeout argument");
1025 free(last_arg_conf);
1029 if ((dhcp_vendor_class_identifier_arg != NULL) && (*dhcp_vendor_class_identifier_arg !=
'\0')) {
1030 if (arg_conf == 0) {
1031 arg_conf_len =
asprintf(&arg_conf,
"send vendor-class-identifier \"%s\";", dhcp_vendor_class_identifier_arg);
1033 if ((arg_conf == 0) || (arg_conf_len <= 0))
1034 log_fatal(
"Unable to send -V option vendor-class-identifier");
1036 char *last_arg_conf = arg_conf;
1038 arg_conf_len =
asprintf(&arg_conf,
"%s\nsend vendor-class-identifier \"%s\";", last_arg_conf, dhcp_vendor_class_identifier_arg);
1040 if ((arg_conf == 0) || (arg_conf_len <= 0))
1041 log_fatal(
"Unable to send -V option vendor-class-identifier");
1043 free(last_arg_conf);
1047 if (dhclient_request_options != NULL) {
1048 if (arg_conf == 0) {
1049 arg_conf_len =
asprintf(&arg_conf,
"request %s;", dhclient_request_options);
1051 if ((arg_conf == 0) || (arg_conf_len <= 0))
1052 log_fatal(
"Unable to parse --request-options <request options list> argument");
1054 char *last_arg_conf = arg_conf;
1056 arg_conf_len =
asprintf(&arg_conf,
"%s\nrequest %s;", last_arg_conf, dhclient_request_options);
1058 if ((arg_conf == 0) || (arg_conf_len <= 0))
1059 log_fatal(
"Unable to parse --request-options <request options list> argument");
1061 free(last_arg_conf);
1066 if (arg_conf_len == 0)
1067 if ((arg_conf_len = strlen(arg_conf)) == 0)
1069 log_fatal(
"Unable to process -C/-H/-F/--timeout/-V/--request-options configuration arguments");
1074 const char *val = NULL;
1077 status =
new_parse(&cfile, -1, arg_conf, arg_conf_len,
"extra dhclient -C/-H/-F/--timeout/-V/--request-options configuration arguments", 0);
1080 log_fatal(
"Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
1092 log_fatal(
"Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
1100 if (
ip->client->config->timeout == 60)
1101 ip->client->config->timeout = timeout_arg;
1149 log_info(
"No broadcast interfaces found - exiting.");
1152 }
else if (!release_mode && !exit_mode) {
1169 if (
ip->client->alias != NULL)
1186 unsigned backup_seed = 0;
1189 if (
ip -> hw_address.hlen <=
sizeof seed )
1192 &
ip -> hw_address.hbuf [
ip -> hw_address.hlen -
1193 sizeof seed],
sizeof seed);
1215 if (
ip -> hw_address.hlen <=
sizeof seed )
1218 &
ip->hw_address.hbuf[
ip->hw_address.hlen -
1219 sizeof seed],
sizeof seed);
1223 if ( seed_flag == 0 ) {
1224 if ( backup_seed != 0 ) {
1226 log_info (
"xid: rand init seed (0x%x) built using all"
1227 " available interfaces",seed);
1230 seed =
cur_time^((unsigned) gethostid()) ;
1231 log_info (
"xid: warning: no netdev with useable HWADDR found"
1232 " for seed's uniqueness enforcement");
1233 log_info (
"xid: rand init seed (0x%x) built using gethostid",
1238 srandom(seed + ((
unsigned)(
cur_tv.tv_usec * 1000000)) + (
unsigned)getpid());
1241 srandom(seed + ((
unsigned)(
cur_tv.tv_usec * 1000000)) + (
unsigned)getpid());
1247 setup_ib_interface(
ip);
1266 #if defined(DHCPv6) && defined(DHCP4o6)
1268 dhcp4o6_setup(dhcp4o6_port);
1275 for (client =
ip->client ; client != NULL ;
1276 client = client->
next) {
1280 }
else if (exit_mode) {
1300 for (client =
ip->client ; client ;
1301 client = client->
next) {
1318 tv.tv_usec = random()
1354 log_fatal(
"Can't allocate new generic object: %s\n",
1355 isc_result_totext(result));
1361 log_fatal(
"Can't start OMAPI protocol: %s",
1362 isc_result_totext (result));
1371 #if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
1372 defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1373 dmalloc_cutoff_generation = dmalloc_generation;
1374 dmalloc_longterm = dmalloc_outstanding;
1375 dmalloc_outstanding = 0;
1378 #if defined(ENABLE_GENTLE_SHUTDOWN)
1415 isc_result_t result;
1424 usage(
"No interfaces available for stateless command: %s",
"-S");
1467 dhcp4o6_setup(port);
1488 log_fatal(
"Can't allocate new generic object: %s\n",
1489 isc_result_totext(result));
1495 log_fatal(
"Can't start OMAPI protocol: %s",
1496 isc_result_totext(result));
1502 #if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
1503 defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1504 dmalloc_cutoff_generation = dmalloc_generation;
1505 dmalloc_longterm = dmalloc_outstanding;
1506 dmalloc_outstanding = 0;
1528 const char *s,
const char *
file,
int line)
1563 ip->client->config->bootp_broadcast_always = 1;
1569 for (g =
ip->client->config->on_transmission; g != NULL; g = g->
next) {
1572 "dhcp-client-identifier") == 0)) {
1578 log_fatal(
"dhcp-client-identifier must be specified for InfiniBand");
1615 #if defined(DHCPv6) && defined(DHCP4o6)
1617 if (dhcp4o6_state < 0)
1628 client ->
active -> is_bootp ||
1642 client ->
xid = random ();
1711 for (lp = client -> offered_leases; lp; lp =
next) {
1720 picked ->
next = NULL;
1725 client -> offered_leases = NULL;
1732 client -> state =
S_INIT;
1739 client ->
new = picked;
1757 client -> first_sending =
cur_time;
1758 client -> interval = client -> config -> initial_interval;
1762 client -> xid = client ->
packet.xid;
1785 for (client =
ip -> client; client; client = client -> next) {
1786 if (client -> xid ==
packet -> raw -> xid)
1790 (
packet -> interface -> hw_address.hlen - 1 !=
1791 packet -> raw -> hlen) ||
1792 (memcmp (&
packet -> interface -> hw_address.hbuf [1],
1795 log_debug (
"DHCPACK in wrong transaction.");
1809 log_info (
"DHCPACK of %s from %s (xid=0x%x)",
1812 ntohl(client -> xid));
1816 log_info (
"packet_to_lease failed.");
1820 client ->
new =
lease;
1828 memset (&ds, 0,
sizeof ds);
1831 packet -> options, client ->
new -> options,
1836 client ->
new -> expiry = 0;
1839 client ->
new -> expiry = 0;
1844 log_error (
"no expiry time on offered lease.");
1850 tv.tv_sec =
cur_tv.tv_sec;
1851 tv.tv_usec =
cur_tv.tv_usec + 500000;
1853 if (tv.tv_usec >= 1000000) {
1855 tv.tv_usec -= 1000000;
1874 packet -> options, client ->
new -> options,
1879 client ->
new -> renewal = 0;
1882 client ->
new -> renewal = 0;
1885 if (!client ->
new -> renewal)
1886 client ->
new -> renewal = client ->
new -> expiry / 2 + 1;
1888 if (client ->
new -> renewal <= 0)
1889 client ->
new -> renewal =
TIME_MAX;
1894 (((random() % client->
new->
renewal) + 3) / 4);
1901 packet -> options, client ->
new -> options,
1906 client ->
new -> rebind = 0;
1909 client ->
new -> rebind = 0;
1911 if (client ->
new -> rebind <= 0) {
1912 if (client ->
new -> expiry <=
TIME_MAX / 7)
1913 client ->
new -> rebind =
1914 client ->
new -> expiry * 7 / 8;
1916 client ->
new -> rebind =
1917 client ->
new -> expiry / 8 * 7;
1922 if (client ->
new -> renewal > client ->
new -> rebind) {
1923 if (client ->
new -> rebind <=
TIME_MAX / 3)
1924 client ->
new -> renewal =
1925 client ->
new -> rebind * 3 / 4;
1927 client ->
new -> renewal =
1928 client ->
new -> rebind / 4 * 3;
1931 client ->
new -> expiry +=
cur_time;
1933 if (client ->
new -> expiry <
cur_time)
1934 client ->
new -> expiry =
TIME_MAX;
1935 client ->
new -> renewal +=
cur_time;
1936 if (client ->
new -> renewal <
cur_time)
1937 client ->
new -> renewal =
TIME_MAX;
1938 client ->
new -> rebind +=
cur_time;
1939 if (client ->
new -> rebind <
cur_time)
1940 client ->
new -> rebind =
TIME_MAX;
1976 log_info(
"Unable to obtain a lease on first "
1977 "try (declined). Exiting.");
1980 #if defined (CALL_SCRIPT_ON_ONETRY_FAIL)
1989 tv.tv_usec =
cur_tv.tv_usec;
2017 random() % 1000000 :
cur_tv.tv_usec;
2020 log_info(
"bound to %s -- renewal in %ld seconds.",
2026 #if defined (NSUPDATE)
2049 client -> xid = client ->
packet.xid;
2051 memset (&ds, 0,
sizeof ds);
2057 client -> active -> options,
2060 memcpy (client -> destination.iabuf, ds.
data, 4);
2061 client -> destination.len = 4;
2069 client -> first_sending =
cur_time;
2070 client -> interval = client -> config -> initial_interval;
2138 for (ap =
packet -> interface -> client -> config -> reject_list;
2139 ap; ap = ap ->
next) {
2148 log_info(
"BOOTREPLY from %s rejected by rule %s "
2163 void (*handler) (
struct packet *);
2191 ap; ap = ap -> next) {
2200 log_info(
"%s from %s rejected by rule %s mask %s.",
2214 char addrbuf[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")];
2222 ap ; ap = ap->
next) {
2225 log_info(
"%s from %s rejected by rule %s",
2238 log_info(
"RCV: %s message on %s from %s.",
2242 forw_dhcpv4_response(
packet);
2252 log_info(
"RCV: %s message on %s from %s.",
2263 client = client->
next) {
2272 log_info(
"Packet received, but nothing done with it.");
2288 static void forw_dhcpv4_response(
struct packet *
packet)
2298 if (dhcp4o6_state == -1) {
2299 log_info(
"forw_dhcpv4_response: not ready.");
2304 log_error(
"forw_dhcpv4_response: bad address");
2313 log_info(
"DHCPv4-response from %s missing "
2314 "DHCPv4 Message option.",
2319 memset(&enc_opt_data, 0,
sizeof(enc_opt_data));
2322 log_error(
"forw_dhcpv4_response: error evaluating "
2330 "no memory for encapsulated packet.");
2338 memset(&ds, 0,
sizeof(ds));
2340 log_error(
"forw_dhcpv4_response: no memory buffer.");
2344 ds.data = ds.buffer->data;
2345 ds.len = enc_opt_data.len + 16;
2346 memcpy(ds.buffer->data, enc_opt_data.data, enc_opt_data.len);
2347 memcpy(ds.buffer->data + enc_opt_data.len,
2354 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
2356 log_error(
"forw_dhcpv4_response: send(): %m");
2370 static void recv_dhcpv4_response(
struct data_string *raw)
2376 log_error(
"recv_dhcpv4_response: no interfaces.");
2381 memcpy(from.iabuf, raw->
data + (raw->
len - 16), 16);
2388 log_error(
"recv_dhcpv4_response: no memory for packet.");
2400 log_error(
"recv_dhcpv4_response: no memory for options.");
2421 memset(&dp, 0,
sizeof dp);
2455 const char *
name =
packet -> packet_type ?
"DHCPOFFER" :
"BOOTREPLY";
2464 for (client =
ip -> client; client; client = client -> next)
2465 if (client -> xid ==
packet -> raw -> xid)
2472 (
packet -> interface -> hw_address.hlen - 1 !=
2473 packet -> raw -> hlen) ||
2474 (memcmp (&
packet -> interface -> hw_address.hbuf [1],
2477 log_debug (
"%s in wrong transaction.", name);
2482 sprintf (obuf,
"%s of %s from %s", name,
2491 for (i = 0 ; req[i] != NULL ; i++) {
2498 option_code_hash_lookup(&
option,
2503 log_info(
"%s: no %s option.", obuf,
2506 log_info(
"%s: no unknown-%u option.",
2518 if (
lease -> address.len ==
sizeof packet -> raw -> yiaddr &&
2519 !memcmp (
lease -> address.iabuf,
2520 &
packet -> raw -> yiaddr,
lease -> address.len)) {
2528 log_info (
"%s: packet_to_lease failed.", obuf);
2537 if (!
packet -> options_valid || !
packet -> packet_type)
2538 lease -> is_bootp = 1;
2541 lease -> medium = client -> medium;
2544 stop_selecting = (client -> first_sending +
2545 client -> config -> select_interval);
2549 if (
lease -> address.len == client -> requested_address.len &&
2550 !memcmp (
lease -> address.iabuf,
2551 client -> requested_address.iabuf,
2552 client -> requested_address.len)) {
2553 lease -> next = client -> offered_leases;
2554 client -> offered_leases =
lease;
2558 if (!client -> offered_leases)
2559 client -> offered_leases =
lease;
2561 for (lp = client -> offered_leases; lp ->
next;
2571 if (stop_selecting <=
cur_tv.tv_sec)
2574 tv.tv_sec = stop_selecting;
2575 tv.tv_usec =
cur_tv.tv_usec;
2597 log_error(
"packet_to_lease: no memory to record lease.\n");
2608 lease->address.len);
2612 lease->next_srv_addr.len);
2614 memset(&data, 0,
sizeof(data));
2616 if (client -> config -> vendor_space_name) {
2622 client -> config -> vendor_space_name &&
2624 (
struct lease *)0, client,
2628 if (!option_code_hash_lookup(&
option,
2632 "option (%s:%d).",
MDL);
2636 client -> config -> vendor_space_name
2662 if (!(i & 2) &&
packet -> raw -> sname [0]) {
2666 if (!
packet -> raw -> sname [len])
2670 log_error (
"dhcpoffer: no memory for server name.\n");
2675 packet -> raw -> sname, len);
2689 log_error (
"dhcpoffer: no memory for filename.\n");
2714 for (client =
ip -> client; client; client = client ->
next)
2722 packet -> raw -> hlen) ||
2726 log_debug (
"DHCPNAK in wrong transaction.");
2745 log_info (
"DHCPNAK with no active lease.\n");
2778 client -> state =
S_INIT;
2797 interval =
cur_time - client -> first_sending;
2801 if (interval > client -> config ->
timeout) {
2809 if (!client -> offered_leases &&
2810 client -> config -> media) {
2813 if (client -> medium) {
2814 client -> medium = client -> medium -> next;
2817 if (!client -> medium) {
2819 log_fatal (
"No valid media types for %s!",
2820 client -> interface -> name);
2822 client -> config -> media;
2826 log_info (
"Trying medium \"%s\" %d",
2827 client -> medium ->
string, increase);
2855 if (
cur_time + client -> interval >
2856 client -> first_sending + client -> config ->
timeout)
2857 client -> interval =
2858 (client -> first_sending +
2862 if (interval < 65536)
2863 client ->
packet.secs = htons (interval);
2865 client ->
packet.secs = htons (65535);
2866 client -> secs = client ->
packet.secs;
2868 #if defined(DHCPv6) && defined(DHCP4o6)
2870 log_info (
"DHCPDISCOVER interval %ld",
2871 (
long)(client -> interval));
2874 log_info (
"DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
2875 client -> name ? client -> name : client -> interface -> name,
2877 ntohs (
sockaddr_broadcast.sin_port), (
long)(client -> interval), ntohl(client -> xid));
2880 #if defined(DHCPv6) && defined(DHCP4o6)
2882 result = send_dhcpv4_query(client, 1);
2889 #if defined(DHCPv6) && defined(DHCP4o6)
2891 log_error(
"%s:%d: Failed to send %d byte long packet.",
2895 log_error(
"%s:%d: Failed to send %d byte long packet over %s "
2907 tv.tv_usec = client->
interval > 1 ? random() % 1000000 :
cur_tv.tv_usec;
2927 if (!lease_list || !
lease) {
2932 for (cur = *lease_list; cur; cur =
next) {
2937 lease->address.len))) {
2966 if (!lease_list || !
lease) {
2978 for (tail = *lease_list; tail && tail->
next; tail = tail->
next){};
2985 *lease_list =
lease;
2996 log_debug (
"%s: %p addr:%s expires:%ld :is_static? %d",
3017 loop = lp = client -> active;
3019 log_info (
"No DHCPOFFERS received.");
3023 if (!client -> active && client -> leases)
3027 while (client -> active) {
3028 if (client -> active -> expiry >
cur_time) {
3030 (client -> active -> is_static
3031 ?
"fallback" :
"recorded"),
3032 piaddr (client -> active -> address));
3036 client -> active -> medium);
3039 if (client -> alias)
3047 if (cur_time < client -> active -> renewal) {
3049 log_info (
"bound: renewal in %ld %s.",
3050 (
long)(client -> active -> renewal -
3055 random() % 1000000 :
3060 log_info (
"bound: immediate renewal.");
3070 if (!client -> leases) {
3071 client -> leases = client -> active;
3081 client -> active = client -> leases;
3082 client -> leases = client -> leases ->
next;
3087 if (client -> active == loop)
3090 loop = client -> active;
3098 log_info (
"Unable to obtain a lease on first try.%s",
3102 #if defined (CALL_SCRIPT_ON_ONETRY_FAIL)
3110 log_info (
"No working leases in persistent database - sleeping.");
3112 if (client -> alias)
3115 client -> state =
S_INIT;
3118 tv.tv_usec = ((tv.tv_sec -
cur_tv.tv_sec) > 1) ?
3119 random() % 1000000 :
cur_tv.tv_usec;
3131 struct sockaddr_in destination;
3132 struct in_addr from;
3135 const char* rip_str =
"";
3138 interval =
cur_time - client -> first_sending;
3152 interval > client -> config -> reboot_timeout) {
3154 client -> state =
S_INIT;
3163 !client -> medium &&
3164 client -> active -> medium ) {
3165 script_init(client,
"MEDIUM", client -> active -> medium);
3172 client -> medium = client -> active -> medium;
3178 cur_time > client -> active -> expiry) {
3183 if (client -> alias)
3191 if (client -> alias)
3196 client -> state =
S_INIT;
3202 if (!client -> interval)
3203 client -> interval = client -> config -> initial_interval;
3205 client -> interval += ((random () >> 2) %
3206 (2 * client -> interval));
3210 if (client -> interval >
3211 client -> config -> backoff_cutoff)
3212 client -> interval =
3213 ((client -> config -> backoff_cutoff / 2)
3214 + ((random () >> 2) %
3215 client -> config -> backoff_cutoff));
3220 cur_time + client -> interval > client -> active -> expiry)
3221 client -> interval =
3222 client -> active -> expiry -
cur_time + 1;
3228 cur_time > client -> active -> rebind)
3231 memcpy (&destination.sin_addr.s_addr,
3232 client -> destination.iabuf,
3233 sizeof destination.sin_addr.s_addr);
3235 destination.sin_family = AF_INET;
3237 destination.sin_len =
sizeof destination;
3242 memcpy (&from, client -> active -> address.iabuf,
3245 from.s_addr = INADDR_ANY;
3249 client ->
packet.secs = client -> secs;
3251 if (interval < 65536)
3252 client ->
packet.secs = htons (interval);
3254 client ->
packet.secs = htons (65535);
3257 #if defined(DHCPv6) && defined(DHCP4o6)
3262 memset(rip_buf, 0x0,
sizeof(rip_buf));
3270 strncpy(rip_buf, rip_str,
sizeof(rip_buf)-1);
3271 log_info (
"DHCPREQUEST for %s on %s to %s port %d (xid=0x%x)",
3274 inet_ntoa(destination.sin_addr),
3275 ntohs (destination.sin_port),
3276 ntohl(client -> xid));
3278 #if defined(DHCPv6) && defined(DHCP4o6)
3281 if (destination.sin_addr.s_addr == INADDR_BROADCAST)
3283 result = send_dhcpv4_query(client, broadcast);
3285 log_error(
"%s:%d: Failed to send %d byte long packet.",
3290 if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
3292 #if defined(SO_BINDTODEVICE)
3296 log_error(
"%s:%d: Failed to bind fallback interface"
3304 log_error(
"%s:%d: Failed to send %d byte long packet "
3305 "over %s interface.",
MDL,
3309 #if defined(SO_BINDTODEVICE)
3311 SO_BINDTODEVICE, NULL, 0) < 0) {
3312 log_fatal(
"%s:%d: Failed to unbind fallback interface:"
3323 log_error(
"%s:%d: Failed to send %d byte long packet"
3324 " over %s interface.",
MDL,
3331 tv.tv_usec = ((tv.tv_sec -
cur_tv.tv_sec) > 1) ?
3332 random() % 1000000 :
cur_tv.tv_usec;
3343 #if defined(DHCPv6) && defined(DHCP4o6)
3348 log_info (
"DHCPDECLINE of %s on %s to %s port %d (xid=0x%x)",
3353 ntohl(client ->
xid));
3357 #if defined(DHCPv6) && defined(DHCP4o6)
3359 result = send_dhcpv4_query(client, 1);
3366 #if defined(DHCPv6) && defined(DHCP4o6)
3368 log_error(
"%s:%d: Failed to send %d byte long packet.",
3372 log_error(
"%s:%d: Failed to send %d byte long packet over %s"
3384 struct sockaddr_in destination;
3385 struct in_addr from;
3387 memcpy (&from, client -> active -> address.iabuf,
3389 memcpy (&destination.sin_addr.s_addr,
3390 client -> destination.iabuf,
3391 sizeof destination.sin_addr.s_addr);
3393 destination.sin_family = AF_INET;
3395 destination.sin_len =
sizeof destination;
3400 client -> active -> expiry =
3401 client -> active -> renewal =
3402 client -> active -> rebind =
cur_time;
3404 log_error (
"Can't release lease: lease write failed.");
3408 #if defined(DHCPv6) && defined(DHCP4o6)
3413 log_info (
"DHCPRELEASE of %s on %s to %s port %d (xid=0x%x)",
3416 inet_ntoa (destination.sin_addr),
3417 ntohs (destination.sin_port),
3418 ntohl(client -> xid));
3420 #if defined(DHCPv6) && defined(DHCP4o6)
3423 if (destination.sin_addr.s_addr == INADDR_BROADCAST)
3425 result = send_dhcpv4_query(client, broadcast);
3427 log_error(
"%s:%d: Failed to send %d byte long packet.",
3433 #if defined(SO_BINDTODEVICE)
3437 log_error(
"%s:%d: Failed to bind fallback interface"
3445 log_error(
"%s:%d: Failed to send %d byte long packet"
3446 " over %s interface.",
MDL,
3450 #if defined(SO_BINDTODEVICE)
3452 SO_BINDTODEVICE, NULL, 0) < 0) {
3453 log_fatal(
"%s:%d: Failed to unbind fallback interface:"
3463 log_error (
"%s:%d: Failed to send %d byte long packet"
3464 " over %s interface.",
MDL,
3472 #if defined(DHCPv6) && defined(DHCP4o6)
3484 static int send_dhcpv4_query(
struct client_state *client,
int broadcast) {
3489 if (dhcp4o6_state <= 0) {
3490 log_info(
"send_dhcpv4_query: not ready.");
3500 memset(&ds, 0,
sizeof(ds));
3502 log_error(
"Unable to allocate memory for DHCPv4-query.");
3505 ds.data = ds.buffer->data;
3530 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
3532 log_error(
"send_dhcpv4_query: send(): %m");
3545 static void forw_dhcpv4_query(
struct data_string *raw) {
3551 struct sockaddr_in6 sin6;
3552 int i, send_ret, attempt, success;
3554 attempt = success = 0;
3555 memset(&sin6, 0,
sizeof(sin6));
3556 sin6.sin6_family = AF_INET6;
3559 sin6.sin6_len =
sizeof(sin6);
3561 memset(&addrs, 0,
sizeof(addrs));
3563 for (client =
ip->client; client != NULL;
3564 client = client->
next) {
3577 lease->options, NULL,
3579 ((addrs.len %
sizeof(sin6.sin6_addr)) != 0)) {
3583 if (addrs.len == 0) {
3591 if (send_ret == raw->
len)
3595 for (i = 0; i < addrs.len;
3596 i +=
sizeof(sin6.sin6_addr)) {
3597 memcpy(&sin6.sin6_addr, addrs.data + i,
3598 sizeof(sin6.sin6_addr));
3602 if (send_ret == raw->
len)
3609 log_info(
"forw_dhcpv4_query: sent(%d): %d/%d",
3610 raw->
len, success, attempt);
3626 struct buffer *bp = NULL;
3649 log_error (
"can't make requested address cache.");
3675 for (i = 0 ; prl[i] != NULL ; i++)
3680 log_error(
"can't make parameter list buffer.");
3685 for (i = 0 ; prl[i] != NULL ; i++)
3689 if (!(option_code_hash_lookup(&
option,
3714 memset(&client_identifier, 0,
sizeof(client_identifier));
3717 client_identifier.
len,
MDL))
3718 log_fatal(
"no memory for default DUID!");
3736 memcpy(&client_identifier.
buffer->
data + 5 - hw_len,
3741 memcpy(&client_identifier.
buffer->
data+(1+4),
3748 (u_int8_t *)client_identifier.
data,
3749 client_identifier.
len,
3751 log_error (
"can't make requested client id cache..");
3775 memset (&client ->
packet, 0,
sizeof (client ->
packet));
3780 client -> config -> requested_options,
3784 client -> packet_length =
3786 (
struct lease *)0, client,
3795 client -> config -> vendor_space_name);
3802 client ->
packet.htype = client ->
interface -> hw_address.hbuf [0];
3804 client ->
packet.hlen = client ->
interface -> hw_address.hlen - 1;
3805 client ->
packet.hops = 0;
3806 client ->
packet.xid = random ();
3807 client ->
packet.secs = 0;
3811 client ->
packet.flags = 0;
3815 memset (&(client ->
packet.ciaddr),
3816 0,
sizeof client ->
packet.ciaddr);
3817 memset (&(client ->
packet.yiaddr),
3818 0,
sizeof client ->
packet.yiaddr);
3819 memset (&(client ->
packet.siaddr),
3820 0,
sizeof client ->
packet.siaddr);
3822 if (client -> interface -> hw_address.hlen > 0)
3823 memcpy (client ->
packet.chaddr,
3824 &client -> interface -> hw_address.hbuf [1],
3825 (
unsigned)(client -> interface -> hw_address.hlen - 1));
3828 dump_raw ((
unsigned char *)&client ->
packet, client -> packet_length);
3840 memset (&client ->
packet, 0,
sizeof (client ->
packet));
3848 if (client -> sent_options)
3855 : (
struct iaddr *)0),
3856 client -> config -> requested_options,
3857 &client -> sent_options);
3860 client -> packet_length =
3862 (
struct lease *)0, client,
3865 client -> sent_options,
3871 client -> config -> vendor_space_name);
3877 client ->
packet.htype = client ->
interface -> hw_address.hbuf [0];
3879 client ->
packet.hlen = client ->
interface -> hw_address.hlen - 1;
3880 client ->
packet.hops = 0;
3881 client ->
packet.xid = client -> xid;
3882 client ->
packet.secs = 0;
3886 if (client -> state ==
S_BOUND ||
3889 memcpy (&client ->
packet.ciaddr,
3890 lease -> address.iabuf,
lease -> address.len);
3891 client ->
packet.flags = 0;
3893 memset (&client ->
packet.ciaddr, 0,
3894 sizeof client ->
packet.ciaddr);
3896 client ->config->bootp_broadcast_always)) &&
3898 client ->
packet.flags = 0;
3903 memset (&client ->
packet.yiaddr, 0,
3904 sizeof client ->
packet.yiaddr);
3905 memset (&client ->
packet.siaddr, 0,
3906 sizeof client ->
packet.siaddr);
3907 if (client -> state !=
S_BOUND &&
3911 memset (&client ->
packet.giaddr, 0,
3912 sizeof client ->
packet.giaddr);
3913 if (client -> interface -> hw_address.hlen > 0)
3914 memcpy (client ->
packet.chaddr,
3915 &client -> interface -> hw_address.hbuf [1],
3916 (
unsigned)(client -> interface -> hw_address.hlen - 1));
3919 dump_raw ((
unsigned char *)&client ->
packet, client -> packet_length);
3939 memset (&client ->
packet, 0,
sizeof (client ->
packet));
3940 client -> packet_length =
3942 (
struct lease *)0, client, 0,
3945 client -> config -> vendor_space_name);
3954 client ->
packet.htype = client ->
interface -> hw_address.hbuf [0];
3956 client ->
packet.hlen = client ->
interface -> hw_address.hlen - 1;
3957 client ->
packet.hops = 0;
3958 client ->
packet.xid = client -> xid;
3959 client ->
packet.secs = 0;
3962 client ->
packet.flags = 0;
3967 memset (&client ->
packet.ciaddr, 0,
3968 sizeof client ->
packet.ciaddr);
3969 memset (&client ->
packet.yiaddr, 0,
3970 sizeof client ->
packet.yiaddr);
3971 memset (&client ->
packet.siaddr, 0,
3972 sizeof client ->
packet.siaddr);
3974 memcpy (client ->
packet.chaddr,
3975 &client -> interface -> hw_address.hbuf [1],
3976 client -> interface -> hw_address.hlen);
3979 dump_raw ((
unsigned char *)&client ->
packet, client -> packet_length);
3992 memset (&client ->
packet, 0,
sizeof (client ->
packet));
3999 client -> packet_length =
4001 (
struct lease *)0, client,
4010 client -> config -> vendor_space_name);
4017 client ->
packet.htype = client ->
interface -> hw_address.hbuf [0];
4019 client ->
packet.hlen = client ->
interface -> hw_address.hlen - 1;
4020 client ->
packet.hops = 0;
4021 client ->
packet.xid = random ();
4022 client ->
packet.secs = 0;
4023 client ->
packet.flags = 0;
4024 memcpy (&client ->
packet.ciaddr,
4025 lease -> address.iabuf,
lease -> address.len);
4026 memset (&client ->
packet.yiaddr, 0,
4027 sizeof client ->
packet.yiaddr);
4028 memset (&client ->
packet.siaddr, 0,
4029 sizeof client ->
packet.siaddr);
4031 memcpy (client ->
packet.chaddr,
4032 &client -> interface -> hw_address.hbuf [1],
4033 client -> interface -> hw_address.hlen);
4036 dump_raw ((
unsigned char *)&client ->
packet, client -> packet_length);
4075 for (client =
ip -> client; client; client = client ->
next) {
4076 for (lp = client -> leases; lp; lp = lp ->
next) {
4079 if (client -> active)
4081 client -> active, 1, 0);
4096 for (client =
ip -> client; client; client = client ->
next) {
4097 for (lp = client -> leases; lp; lp = lp ->
next) {
4100 if (client -> active)
4102 client -> active, 1, 0);
4124 const char *name, *dot;
4126 char *preamble = stuff;
4128 memset (&ds, 0,
sizeof ds);
4138 in_options, cfg_options, scope, oc,
MDL)) {
4140 fprintf(
leaseFile,
"%soption %s%s%s", preamble,
4161 const char *preamble)
4174 if (c >=
'0' && c <=
'9')
4177 if (c >=
'a' && c <=
'f')
4178 return c -
'a' + 10;
4180 if (c >=
'A' && c <=
'F')
4181 return c -
'A' + 10;
4188 const char *id_fname =
"/etc/machine-id";
4191 FILE *
file = fopen( id_fname ,
"r");
4194 return ISC_R_IOERROR;
4196 nread = fread(
id, 1,
sizeof id,
file);
4200 log_debug(
"Not enough data in %s", id_fname);
4201 return ISC_R_IOERROR;
4204 for (j = 0; j < 16; j++) {
4210 if (a < 0 || b < 0) {
4211 log_debug(
"Wrong data in %s", id_fname);
4212 return ISC_R_IOERROR;
4214 uuid[j] = a << 4 | b;
4218 uuid[6] = (uuid[6] & 0x0F) | 0x40;
4220 uuid[8] = (uuid[8] & 0x3F) | 0x80;
4255 log_debug(
"Cannot form default DUID from interface %s.",
ip->name);
4259 return ISC_R_UNEXPECTED;
4262 if ((
ip->hw_address.hlen == 0) ||
4263 (
ip->hw_address.hlen >
sizeof(
ip->hw_address.hbuf)))
4264 log_fatal(
"Impossible hardware address length at %s:%d.",
MDL);
4274 len = 2 +
sizeof (uuid);
4283 len = 4 + (
ip->hw_address.hlen - 1);
4288 log_fatal(
"no memory for default DUID!");
4294 memcpy(duid->
buffer->
data + 2, uuid,
sizeof(uuid));
4301 memcpy(duid->
buffer->
data + 8,
ip->hw_address.hbuf + 1,
4302 ip->hw_address.hlen - 1);
4306 memcpy(duid->
buffer->
data + 4,
ip->hw_address.hbuf + 1,
4307 ip->hw_address.hlen - 1);
4314 log_info(
"form_duid: Couldn't allocate memory to log duid!");
4330 if ((duid == NULL) || (duid->
len <= 2))
4337 return ISC_R_IOERROR;
4345 return ISC_R_NOMEMORY;
4347 stat = fprintf(
leaseFile,
"default-duid %s;\n", str);
4350 return ISC_R_IOERROR;
4353 return ISC_R_IOERROR;
4361 int rewrite,
int sync)
4375 if (client == NULL ||
lease == NULL)
4382 return ISC_R_IOERROR;
4386 stat = fprintf(
leaseFile,
"lease6 {\n");
4388 return ISC_R_IOERROR;
4390 stat = fprintf(
leaseFile,
" interface \"%s\";\n",
4393 return ISC_R_IOERROR;
4395 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
4416 (
const unsigned char *) &ia->
iaid, 4,
4421 return ISC_R_IOERROR;
4432 stat = fprintf(
leaseFile,
" %s %s {\n", ianame,
4438 return ISC_R_IOERROR;
4441 stat = fprintf(
leaseFile,
" starts %d;\n"
4446 stat = fprintf(
leaseFile,
" starts %d;\n",
4449 return ISC_R_IOERROR;
4451 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4458 " iaprefix %s/%d {\n",
4462 return ISC_R_IOERROR;
4464 stat = fprintf(
leaseFile,
" starts %d;\n"
4465 " preferred-life %u;\n"
4470 return ISC_R_IOERROR;
4473 write_options(client, addr->
options,
" ");
4477 return ISC_R_IOERROR;
4481 write_options(client, ia->
options,
" ");
4485 return ISC_R_IOERROR;
4488 if (
lease->released) {
4489 stat = fprintf(
leaseFile,
" released;\n");
4491 return ISC_R_IOERROR;
4494 if (
lease->options != NULL)
4495 write_options(client,
lease->options,
" ");
4499 return ISC_R_IOERROR;
4502 return ISC_R_IOERROR;
4506 log_error(
"write_client_lease: fsync(): %m");
4507 return ISC_R_IOERROR;
4534 if (
lease -> is_static)
4547 if (
lease -> is_bootp) {
4554 fprintf (
leaseFile,
" interface \"%s\";\n",
4555 client -> interface -> name);
4560 if (client -> name) {
4561 fprintf (
leaseFile,
" name \"%s\";\n", client -> name);
4567 fprintf (
leaseFile,
" fixed-address %s;\n",
4573 if (
lease -> filename) {
4576 fprintf (
leaseFile,
" filename \"%s\";\n", s);
4586 if (
lease->server_name != NULL) {
4589 fprintf(
leaseFile,
" server-name \"%s\";\n", s);
4598 if (
lease -> medium) {
4601 fprintf (
leaseFile,
" medium \"%s\";\n", s);
4615 memset (&ds, 0,
sizeof ds);
4617 write_options(client,
lease->options,
" ");
4621 fprintf(
leaseFile,
" renew %s\n", tval) < 0)
4626 fprintf(
leaseFile,
" rebind %s\n", tval) < 0)
4631 fprintf(
leaseFile,
" expire %s\n", tval) < 0)
4642 if (!errors && makesure) {
4644 log_info (
"write_client_lease: %m");
4649 return errors ? 0 : 1;
4676 for (sl = client -> env; sl; sl =
next) {
4683 if (client -> interface) {
4685 client -> interface -> name);
4689 "",
"client",
"%s", client -> name);
4692 "",
"medium",
"%s", medium ->
string);
4695 client_envadd (client,
"",
"pid",
"%ld", (
long int)getpid ());
4698 (
long int)dad_wait_time);
4716 in_options, cfg_options, scope, oc,
MDL)) {
4726 length = strlen(
value);
4730 value, length) == 0) {
4735 "option - discarded",
4780 if (
lease->next_srv_addr.len != 0) {
4792 memset (&data, 0,
sizeof data);
4823 (&data, (
struct packet *)0,
4824 (
struct lease *)0, client,
4829 if (broadcast.
len) {
4831 prefix,
"broadcast_address",
4832 "%s",
piaddr (broadcast));
4840 if (
lease->filename) {
4843 strlen(
lease->filename)) == 0) {
4845 "%s",
lease->filename);
4848 "option - discarded",
4853 if (
lease->server_name) {
4856 strlen(
lease->server_name)) == 0 ) {
4858 "%s",
lease->server_name);
4861 "option - discarded",
4862 lease->server_name);
4875 (
unsigned long)(
lease -> expiry));
4897 for (i = 0 ; req[i] != NULL ; i++) {
4922 char reason [] =
"REASON=NBI";
4923 static char client_path [] = CLIENT_PATH;
4926 int pid, wpid, wstatus;
4929 scriptName = client -> config -> script_name;
4933 envp =
dmalloc (((client ? client -> envc : 2) +
4936 log_error (
"No memory for client script environment.");
4943 envp [i++] = sp ->
string;
4947 for (sp = client -> env; sp; sp = sp ->
next) {
4948 envp [i++] = sp ->
string;
4951 envp [i++] = reason;
4954 envp [i++] = client_path;
4955 envp [i] = (
char *)0;
4958 argv [1] = (
char *)0;
4966 wpid = wait (&wstatus);
4967 }
while (wpid != pid && wpid > 0);
4984 for (sp = client -> env; sp; sp =
next) {
4992 gettimeofday(&
cur_tv, NULL);
4993 return (WIFEXITED (wstatus) ?
4994 WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
4998 const char *prefix,
const char *name,
const char *fmt, ...)
5006 va_start (list, fmt);
5007 len = vsnprintf (spbuf,
sizeof spbuf, fmt, list);
5010 val =
dmalloc (strlen (prefix) + strlen (name) + 1 +
5011 len +
sizeof *val,
MDL);
5013 log_error (
"client_envadd: cannot allocate space for variable");
5022 if (len >=
sizeof spbuf) {
5023 va_start (list, fmt);
5024 vsnprintf (s, len + 1, fmt, list);
5030 val ->
next = client -> env;
5031 client -> env = val;
5054 if (j + 1 == buflen)
5064 if (j + 1 == buflen)
5079 if (write(
dfd[1], &ret, 1) != 1)
5081 (void) close(
dfd[1]);
5097 if (
dfd[0] == -1 ||
dfd[1] == -1)
5101 if (write(
dfd[1], &buf, 1) != 1)
5103 (void) close(
dfd[1]);
5118 (void) open(
"/dev/null", O_RDWR | O_CLOEXEC);
5119 (void) open(
"/dev/null", O_RDWR | O_CLOEXEC);
5120 (void) open(
"/dev/null", O_RDWR | O_CLOEXEC);
5138 pfdesc = open (
path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
5145 pf = fdopen (pfdesc,
"we");
5150 fprintf (pf,
"%ld\n", (
long)getpid ());
5161 for (client =
ip -> client; client; client = client ->
next) {
5162 switch (client ->
state) {
5195 #if defined(DHCPv6) && defined(DHCP4o6)
5197 if (dhcp4o6_state < 0)
5205 client -> xid = random ();
5208 if (client -> active) {
5213 memset (&ds, 0,
sizeof ds);
5215 client -> active -> options,
5219 (
struct lease *)0, client,
5221 client -> active -> options,
5224 memcpy (client -> destination.iabuf,
5226 client -> destination.len = 4;
5233 client -> first_sending =
cur_time;
5234 client -> interval = client -> config -> initial_interval;
5245 if (client -> alias)
5261 #if defined(DHCPv6) && defined(DHCP4o6)
5284 interface_reference (&
ip, last ->
next,
MDL);
5285 interface_dereference (&last ->
next,
MDL);
5287 interface_reference (&last ->
next,
5289 interface_dereference (&
ip ->
next,
5294 interface_reference (&
ip,
5300 interface_dereference (&
ip ->
next,
5307 tmp ->
client ->
interface = tmp;
5309 interface_dereference (&
ip,
MDL);
5358 for (client =
ip->client ; client ; client = client->
next) {
5389 static void shutdown_exit (
void *foo)
5397 #if defined (NSUPDATE)
5414 isc_result_t eresult)
5417 isc_result_t result;
5431 dhclient_ddns_cb_free(ddns_cb,
MDL);
5440 isc_result_t result;
5443 if (client->
ddns_cb != NULL) {
5449 if (ddns_cb != NULL) {
5455 ddns_cb->
cur_func = client_dns_remove_action;
5459 if (result != ISC_R_TIMEDOUT) {
5460 dhclient_ddns_cb_free(ddns_cb,
MDL);
5481 log_info(
"Received signal %d, initiating shutdown.",
5490 for (client =
ip -> client; client; client = client -> next) {
5499 if (client -> active &&
5500 client -> active -> expiry >
cur_time) {
5501 #if defined (NSUPDATE)
5530 tv.tv_sec =
cur_tv.tv_sec;
5531 tv.tv_usec =
cur_tv.tv_usec + 1;
5537 #if defined (NSUPDATE)
5548 isc_result_t status = ISC_R_FAILURE;
5550 if ((client != NULL) &&
5551 ((client->
active != NULL) ||
5564 if (status != ISC_R_TIMEDOUT) {
5600 isc_result_t eresult)
5602 isc_result_t result;
5619 ddns_cb->
cur_func = client_dns_update_action;
5628 case ISC_R_TIMEDOUT:
5636 if (ddns_cb->
zone != NULL) {
5642 ddns_cb->
cur_func = client_dns_update_action;
5648 tv.tv_usec =
cur_tv.tv_usec;
5650 ddns_cb, NULL, NULL);
5654 dhclient_ddns_cb_free(ddns_cb,
MDL);
5672 if (!client -> sent_options)
5683 (
struct lease *)0, client,
5684 client -> sent_options,
5694 (
struct lease *)0, client,
5695 client -> sent_options,
5704 (
struct lease *)0, client,
5705 client -> sent_options,
5720 memset(&client_identifier, 0,
sizeof(client_identifier));
5744 client_identifier.data,
5745 client_identifier.len);
5763 (client_identifier.data[0] == 255)) {
5768 if (client_identifier.len <= 5)
5769 log_fatal(
"Impossible condition at %s:%d.",
5772 client_identifier.data + 5,
5773 client_identifier.len - 5);
5775 result =
get_dhcid(ddns_cb, ddns_v4_type,
5776 client_identifier.data,
5777 client_identifier.len);
5796 rcode = ISC_R_FAILURE;
5803 rcode = ISC_R_TIMEDOUT;
5826 if (client->
ddns_cb != NULL) {
5833 if (ddns_cb != NULL) {
5834 ddns_cb->
lease = (
void *)client;
5847 ddns_cb->
cur_func = client_dns_update_action;
5851 tv.tv_sec =
cur_tv.tv_sec + offset;
5852 tv.tv_usec =
cur_tv.tv_usec;
5854 ddns_cb, NULL, NULL);
5856 log_error(
"Unable to allocate dns update state for %s",
5865 struct servent *ent;
5879 ent = getservbyname(
"dhcpc",
"udp");
5881 ent = getservbyname(
"bootpc",
"udp");
5886 #ifndef __CYGWIN32__
5910 static int check_domain_name(
const char *ptr,
size_t len,
int dots)
5915 if ((len == 0) || (len > 256))
5920 for (p=ptr; (*p != 0) && (len-- > 0); p++) {
5921 if ((*p ==
'-') || (*p ==
'_')) {
5923 if (((p - ptr) == 0) || (len == 0) || (p[1] ==
'.'))
5925 }
else if (*p ==
'.') {
5929 if ((d <= 0) || (d >= 64))
5932 if ((dots > 0) && (len > 0))
5934 }
else if (isalnum((
unsigned char)*p) == 0) {
5939 return(dots ? -1 : 0);
5942 static int check_domain_name_list(
const char *ptr,
size_t len,
int dots)
5947 if ((ptr == NULL) || (len == 0))
5950 for (p=ptr; (*p != 0) && (len > 0); p++, len--) {
5954 if (check_domain_name(ptr, p - ptr, dots) != 0)
5961 return(check_domain_name(ptr, p - ptr, dots));
5978 #ifdef ACCEPT_LIST_IN_DOMAIN_NAME
5979 return check_domain_name_list(ptr, len, 0);
5981 return check_domain_name(ptr, len, 0);
5986 return check_domain_name(ptr, len, 0);
5989 return check_domain_name_list(ptr, len, 0);
5994 for (; (*ptr != 0) && (len-- > 0); ptr++) {
5995 if(!(isalnum((
unsigned char)*ptr) ||
5996 *ptr ==
'#' || *ptr ==
'%' ||
5997 *ptr ==
'+' || *ptr ==
'-' ||
5998 *ptr ==
'_' || *ptr ==
':' ||
5999 *ptr ==
'.' || *ptr ==
',' ||
6000 *ptr ==
'@' || *ptr ==
'~' ||
6001 *ptr ==
'\\' || *ptr ==
'/' ||
6002 *ptr ==
'[' || *ptr ==
']' ||
6003 *ptr ==
'=' || *ptr ==
' '))
6018 return check_domain_name_list(ptr, len, 0);
6033 log_fatal (
"no memory for reject list!");
6052 log_info(
"Server added to list of rejected servers.");
6055 #if defined(NSUPDATE)
6062 if (client != NULL) {
6071 #if defined(DHCPv6) && defined(DHCP4o6)
6090 char start_msg[5] = {
'S',
'T',
'A',
'R',
'T' };
6091 char stop_msg[4] = {
'S',
'T',
'O',
'P' };
6092 char poll_msg[4] = {
'P',
'O',
'L',
'L' };
6096 if (h->type != dhcp4o6_type)
6099 cc = recv(dhcp4o6_fd, buf,
sizeof(buf), 0);
6101 return ISC_R_UNEXPECTED;
6105 (memcmp(buf, poll_msg,
sizeof(poll_msg)) == 0)) {
6107 if (dhcp4o6_state < 0)
6108 cc = send(dhcp4o6_fd, stop_msg,
6109 sizeof(stop_msg), 0);
6111 cc = send(dhcp4o6_fd, start_msg,
6112 sizeof(start_msg), 0);
6114 log_error(
"dhcpv4o6_handler: send(): %m");
6115 return ISC_R_IOERROR;
6119 return ISC_R_UNEXPECTED;
6120 memset(&raw, 0,
sizeof(raw));
6123 "no memory buffer.");
6124 return ISC_R_NOMEMORY;
6130 forw_dhcpv4_query(&raw);
6136 (memcmp(buf, stop_msg,
sizeof(stop_msg)) == 0)) {
6138 if (dhcp4o6_state > 0) {
6142 }
else if ((cc == 5) &&
6143 (memcmp(buf, start_msg,
sizeof(start_msg)) == 0)) {
6145 if (dhcp4o6_state == 0)
6151 return ISC_R_UNEXPECTED;
6152 memset(&raw, 0,
sizeof(raw));
6155 "no memory buffer.");
6156 return ISC_R_NOMEMORY;
6162 recv_dhcpv4_response(&raw);
6179 static void dhcp4o6_poll(
void *dummy) {
6180 char msg[4] = {
'P',
'O',
'L',
'L' };
6186 if (dhcp4o6_state < 0)
6191 cc = send(dhcp4o6_fd, msg,
sizeof(msg), 0);
6196 tv.tv_usec = random() % 1000000;
6208 static void dhcp4o6_resume() {
6213 for (client =
ip->client; client != NULL;
6214 client = client->
next) {
6237 char msg[5] = {
'S',
'T',
'A',
'R',
'T' };
6240 memset(&addrs, 0,
sizeof(addrs));
6242 for (client =
ip->client; client != NULL;
6243 client = client->
next) {
6256 lease->options, NULL,
6259 if ((addrs.len % 16) != 0) {
6272 if (dhcp4o6_state == 1)
6274 log_info(
"dhcp4o6_start: go to UP");
6277 cc = send(dhcp4o6_fd, msg,
sizeof(msg), 0);
6279 log_info(
"dhcp4o6_start: send(): %m");
6289 static void dhcp4o6_stop() {
6290 char msg[4] = {
'S',
'T',
'O',
'P' };
6293 if (dhcp4o6_state == -1)
6296 log_info(
"dhcp4o6_stop: go to DOWN");
6299 cc = send(dhcp4o6_fd, msg,
sizeof(msg), 0);