36#include <dns/result.h>
52extern int asprintf(
char **strp,
const char *fmt, ...);
87#define ASSERT_STATE(state_is, state_shouldbe) {}
90static const char copyright[] =
"Copyright 2004-2022 Internet Systems Consortium.";
91static const char arr [] =
"All rights reserved.";
92static const char message [] =
"Internet Systems Consortium DHCP Client";
93static const char url [] =
"For info, please visit https://www.isc.org/software/dhcp/";
99#if defined(DHCPv6) && defined(DHCP4o6)
100int dhcp4o6_state = -1;
117int dad_wait_time = 0;
118int prefix_len_hint = 0;
132static isc_result_t write_duid(
struct data_string *duid);
135static int check_domain_name(
const char *ptr,
size_t len,
int dots);
136static int check_domain_name_list(
const char *ptr,
size_t len,
int dots);
138 const char *ptr,
size_t len);
162#if defined(DHCPv6) && defined(DHCP4o6)
163static void dhcp4o6_poll(
void *dummy);
164static void dhcp4o6_resume(
void);
165static void recv_dhcpv4_response(
struct data_string *raw);
166static int send_dhcpv4_query(
struct client_state *client,
int broadcast);
168static void dhcp4o6_stop(
void);
170static void forw_dhcpv4_query(
struct data_string *raw);
177static const char use_noarg[] =
"No argument for command: %s";
179static const char use_v6command[] =
"Command not used for DHCPv4: %s";
184#define DHCLIENT_USAGE0 \
185"[-4|-6] [-SNTPRI1dvrxi] [-nw] -4o6 <port>] [-p <port>] [-D LL|LLT]\n" \
186" [--dad-wait-time <seconds>] [--prefix-len-hint <length>]\n" \
187" [--decline-wait-time <seconds>]\n" \
188" [--address-prefix-len <length>]\n"
190#define DHCLIENT_USAGE0 \
191"[-4|-6] [-SNTPRI1dvrxi] [-nw] [-p <port>] [-D LL|LLT]\n" \
192" [--dad-wait-time <seconds>] [--prefix-len-hint <length>]\n" \
193" [--decline-wait-time <seconds>]\n" \
194" [--address-prefix-len <length>]\n"
197#define DHCLIENT_USAGE0 \
198"[-I1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n" \
199" [--decline-wait-time <seconds>]\n"
202#define DHCLIENT_USAGEC \
203" [-s server-addr] [-cf config-file]\n" \
204" [-df duid-file] [-lf lease-file]\n" \
205" [-pf pid-file] [--no-pid] [-e VAR=val]\n" \
206" [-sf script-file] [interface]*\n" \
207" [-C <dhcp-client-identifier>] [-B]\n" \
208" [-H <host-name> | -F <fqdn.fqdn>] [--timeout <timeout>]\n" \
209" [-V <vendor-class-identifier>]\n" \
210" [--request-options <request option list>]"
212#define DHCLIENT_USAGEH "{--version|--help|-h}"
217usage(
const char *sfmt,
const char *sarg)
225#ifdef PRINT_SPECIFIC_CL_ERRORS
250 int release_mode = 0;
255 int no_dhclient_conf = 0;
256 int no_dhclient_db = 0;
257 int no_dhclient_pid = 0;
258 int no_dhclient_script = 0;
260 int local_family_set = 0;
262 u_int16_t dhcp4o6_port = 0;
272 char *dhcp_client_identifier_arg = NULL;
273 char *dhcp_host_name_arg = NULL;
274 char *dhcp_fqdn_arg = NULL;
275 char *dhcp_vendor_class_identifier_arg = NULL;
276 char *dhclient_request_options = NULL;
279 char *arg_conf = NULL;
280 int arg_conf_len = 0;
282 int keep_capabilities = 0;
291 fd = open(
"/dev/null", O_RDWR | O_CLOEXEC);
293 fd = open(
"/dev/null", O_RDWR | O_CLOEXEC);
295 fd = open(
"/dev/null", O_RDWR | O_CLOEXEC);
303#if !(defined(DEBUG) || defined(__CYGWIN32__))
304 setlogmask(LOG_UPTO(LOG_INFO));
308 for (i = 1; i < argc; i++) {
309 if (!strcmp(argv[i],
"-r")) {
311 }
else if (!strcmp(argv[i],
"-x")) {
313 }
else if (!strcmp(argv[i],
"-d")) {
315 }
else if (!strcmp(argv[i],
"--version")) {
316 const char vstring[] =
"isc-dhclient-";
324 }
else if (!strcmp(argv[i],
"--help") ||
325 !strcmp(argv[i],
"-h")) {
326 const char *pname = isc_file_basename(
progname);
350 if ((pid = fork ()) < 0)
356 (void) close(
dfd[1]);
360 n = read(
dfd[0], &buf, 1);
363 }
while (n == -1 && errno == EINTR);
367 (void) close(
dfd[0]);
374 log_fatal(
"Can't initialize context: %s",
375 isc_result_totext(status));
381 isc_result_totext(status));
391 for (i = 1; i < argc; i++) {
392 if (!strcmp(argv[i],
"-r")) {
396 }
else if (!strcmp(argv[i],
"-4")) {
398 log_fatal(
"Client can only do v4 or v6, not "
400 local_family_set = 1;
402 }
else if (!strcmp(argv[i],
"-6")) {
404 log_fatal(
"Client can only do v4 or v6, not "
406 local_family_set = 1;
409 }
else if (!strcmp(argv[i],
"-4o6")) {
411 usage(use_noarg, argv[i-1]);
414 log_debug(
"DHCPv4 over DHCPv6 over ::1 port %d and %d",
416 ntohs(dhcp4o6_port) + 1);
420 }
else if (!strcmp(argv[i],
"-x")) {
424 }
else if (!strcmp(argv[i],
"-p")) {
426 usage(use_noarg, argv[i-1]);
428 log_debug(
"binding to user-specified port %d",
430 }
else if (!strcmp(argv[i],
"-d")) {
433 }
else if (!strcmp(argv[i],
"-pf")) {
435 usage(use_noarg, argv[i-1]);
438 }
else if (!strcmp(argv[i],
"--no-pid")) {
440 }
else if (!strcmp(argv[i],
"-cf")) {
442 usage(use_noarg, argv[i-1]);
444 no_dhclient_conf = 1;
445 }
else if (!strcmp(argv[i],
"-df")) {
447 usage(use_noarg, argv[i-1]);
449 }
else if (!strcmp(argv[i],
"-lf")) {
451 usage(use_noarg, argv[i-1]);
454 }
else if (!strcmp(argv[i],
"-sf")) {
456 usage(use_noarg, argv[i-1]);
458 no_dhclient_script = 1;
459 }
else if (!strcmp(argv[i],
"-1")) {
461 }
else if (!strcmp(argv[i],
"-q")) {
463 }
else if (!strcmp(argv[i],
"-s")) {
465 usage(use_noarg, argv[i-1]);
467 }
else if (!strcmp(argv[i],
"-g")) {
469 usage(use_noarg, argv[i-1]);
471 }
else if (!strcmp(argv[i],
"-nw")) {
473 }
else if (!strcmp(argv[i],
"-n")) {
476 }
else if (!strcmp(argv[i],
"-w")) {
479 }
else if (!strcmp(argv[i],
"-e")) {
482 usage(use_noarg, argv[i-1]);
483 tmp =
dmalloc(strlen(argv[i]) +
sizeof *tmp,
MDL);
486 strcpy(tmp->
string, argv[i]);
491 }
else if (!strcmp(argv[i],
"-S")) {
493 usage(use_v6command, argv[i]);
495 local_family_set = 1;
499 }
else if (!strcmp(argv[i],
"-N")) {
501 usage(use_v6command, argv[i]);
503 local_family_set = 1;
509 }
else if (!strcmp(argv[i],
"-T")) {
511 usage(use_v6command, argv[i]);
513 local_family_set = 1;
519 }
else if (!strcmp(argv[i],
"-P")) {
521 usage(use_v6command, argv[i]);
523 local_family_set = 1;
529 }
else if (!strcmp(argv[i],
"-R")) {
531 usage(use_v6command, argv[i]);
533 local_family_set = 1;
536 }
else if (!strcmp(argv[i],
"--dad-wait-time")) {
538 usage(use_noarg, argv[i-1]);
541 dad_wait_time = (
int)strtol(argv[i], &s, 10);
542 if (errno || (*s !=
'\0') || (dad_wait_time < 0)) {
543 usage(
"Invalid value for --dad-wait-time: %s",
546 }
else if (!strcmp(argv[i],
"--prefix-len-hint")) {
548 usage(use_noarg, argv[i-1]);
552 prefix_len_hint = (
int)strtol(argv[i], &s, 10);
553 if (errno || (*s !=
'\0') || (prefix_len_hint < 0)) {
554 usage(
"Invalid value for --prefix-len-hint: %s",
557 }
else if (!strcmp(argv[i],
"--address-prefix-len")) {
559 usage(use_noarg, argv[i-1]);
563 if (errno || (*s !=
'\0') ||
565 usage(
"Invalid value for"
566 " --address-prefix-len: %s", argv[i]);
569 }
else if (!strcmp(argv[i],
"--decline-wait-time")) {
571 usage(use_noarg, argv[i-1]);
576 if (errno || (*s !=
'\0') ||
578 usage(
"Invalid value for "
579 "--decline-wait-time: %s", argv[i]);
581 }
else if (!strcmp(argv[i],
"-D")) {
584 usage(use_noarg, argv[i-1]);
585 if (!strcasecmp(argv[i],
"LL")) {
587 }
else if (!strcasecmp(argv[i],
"LLT")) {
590 usage(
"Unknown argument to -D: %s", argv[i]);
592 }
else if (!strcmp(argv[i],
"-i")) {
595 }
else if (!strcmp(argv[i],
"-I")) {
598 }
else if (!strcmp(argv[i],
"-v")) {
600 }
else if (!strcmp(argv[i],
"-C")) {
601 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
602 usage(use_noarg, argv[i-1]);
611 dhcp_client_identifier_arg = argv[i];
612 }
else if (!strcmp(argv[i],
"-B")) {
614 }
else if (!strcmp(argv[i],
"-H")) {
615 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
616 usage(use_noarg, argv[i-1]);
625 if (dhcp_host_name_arg != NULL) {
626 log_error(
"The -H <host-name> and -F <fqdn> arguments are mutually exclusive");
630 dhcp_host_name_arg = argv[i];
631 }
else if (!strcmp(argv[i],
"-F")) {
632 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
633 usage(use_noarg, argv[i-1]);
642 if (dhcp_fqdn_arg != NULL) {
643 log_error(
"Only one -F <fqdn> argument can be specified");
647 if (dhcp_host_name_arg != NULL) {
648 log_error(
"The -F <fqdn> and -H <host-name> arguments are mutually exclusive");
652 dhcp_fqdn_arg = argv[i];
653 }
else if (!strcmp(argv[i],
"--timeout")) {
654 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
655 usage(use_noarg, argv[i-1]);
659 if ((timeout_arg = atoi(argv[i])) <= 0) {
660 log_error(
"timeout option must be > 0 - bad value: %s",argv[i]);
663 }
else if (!strcmp(argv[i],
"-V")) {
664 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
665 usage(use_noarg, argv[i-1]);
674 dhcp_vendor_class_identifier_arg = argv[i];
675 }
else if (!strcmp(argv[i],
"--request-options")) {
676 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
677 usage(use_noarg, argv[i-1]);
681 dhclient_request_options = argv[i];
683 }
else if (!strcmp(argv[i],
"-nc")) {
685 keep_capabilities = 1;
687 }
else if (argv[i][0] ==
'-') {
688 usage(
"Unknown command: %s", argv[i]);
690 usage(
"No interfaces command -n and "
691 " requested interface %s", argv[i]);
695 status = interface_allocate(&tmp,
MDL);
697 log_fatal(
"Can't record interface %s:%s",
698 argv[i], isc_result_totext(status));
699 if (strlen(argv[i]) >=
sizeof(tmp->
name))
700 log_fatal(
"%s: interface name too long (is %ld)",
701 argv[i], (
long)strlen(argv[i]));
702 strcpy(tmp->
name, argv[i]);
704 interface_reference(&tmp->
next,
720 usage(
"PD %s only supports one requested interface",
"-P");
723#if defined(DHCPv6) && defined(DHCP4o6)
725 (exit_mode || release_mode))
726 log_error(
"Can't relay DHCPv4-over-DHCPv6 "
727 "without a persistent DHCPv6 client");
730 log_fatal(
"DHCPv4-over-DHCPv6 requires an explicit "
731 "interface on which to be applied");
734 if (!no_dhclient_conf && (s = getenv(
"PATH_DHCLIENT_CONF"))) {
737 if (!no_dhclient_db && (s = getenv(
"PATH_DHCLIENT_DB"))) {
740 if (!no_dhclient_pid && (s = getenv(
"PATH_DHCLIENT_PID"))) {
743 if (!no_dhclient_script && (s = getenv(
"PATH_DHCLIENT_SCRIPT"))) {
749 if (!keep_capabilities) {
750 capng_clear(CAPNG_SELECT_CAPS);
751 capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
753 capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
754 CAP_NET_ADMIN, CAP_NET_RAW,
755 CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1);
756 capng_apply(CAPNG_SELECT_CAPS);
801 e = fscanf(pidfd,
"%ld\n", &temp);
802 oldpid = (pid_t)temp;
804 if (e != 0 && e != EOF && oldpid) {
805 if (kill(oldpid, SIGTERM) == 0) {
806 log_info(
"Killed old client process");
816 }
else if (errno == ESRCH) {
830 char *new_path_dhclient_pid;
849 int n_len = strlen(
ip->name);
851 new_path_dhclient_pid = (
char*) malloc(pfx + n_len + 6);
853 sprintf(new_path_dhclient_pid + pfx,
"-%s.pid",
ip->name);
855 if ((pidfd = fopen(new_path_dhclient_pid,
"re")) != NULL) {
856 e = fscanf(pidfd,
"%ld\n", &temp);
857 oldpid = (pid_t)temp;
859 if (e != 0 && e != EOF) {
861 if (kill(oldpid, SIGTERM) == 0)
869 free(new_path_dhclient_pid);
878 char procfn[256] =
"";
881 if ((fscanf(pidfp,
"%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
882 snprintf(procfn,256,
"/proc/%u",dhcpid);
883 dhc_running = (access(procfn, F_OK) == 0);
890 log_fatal(
"dhclient(%u) is already running - exiting. ", dhcpid);
915 memcpy(&
giaddr, he->h_addr_list[0],
924 gettimeofday(&
cur_tv, NULL);
931 he = gethostbyname(server);
957 usage(
"Stateless command: %s incompatibile with "
958 "other commands",
"-S");
960#if defined(DHCPv6) && defined(DHCP4o6)
969 if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg !=
'\0')) {
970 arg_conf_len =
asprintf(&arg_conf,
"send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);
972 if ((arg_conf == 0) || (arg_conf_len <= 0))
973 log_fatal(
"Unable to send -C option dhcp-client-identifier");
976 if ((dhcp_host_name_arg != NULL) && (*dhcp_host_name_arg !=
'\0')) {
978 arg_conf_len =
asprintf(&arg_conf,
"send host-name \"%s\";", dhcp_host_name_arg);
980 if ((arg_conf == 0) || (arg_conf_len <= 0))
981 log_fatal(
"Unable to send -H option host-name");
983 char *last_arg_conf = arg_conf;
985 arg_conf_len =
asprintf(&arg_conf,
"%s\nsend host-name \"%s\";", last_arg_conf, dhcp_host_name_arg);
987 if ((arg_conf == 0) || (arg_conf_len <= 0))
988 log_fatal(
"Unable to send -H option host-name");
994 if ((dhcp_fqdn_arg != NULL) && (*dhcp_fqdn_arg !=
'\0')) {
996 arg_conf_len =
asprintf(&arg_conf,
"send fqdn.fqdn \"%s\";", dhcp_fqdn_arg);
998 if ((arg_conf == 0) || (arg_conf_len <= 0))
999 log_fatal(
"Unable to send -F option fqdn.fqdn");
1001 char *last_arg_conf = arg_conf;
1003 arg_conf_len =
asprintf(&arg_conf,
"%s\nsend fqdn.fqdn \"%s\";", last_arg_conf, dhcp_fqdn_arg);
1005 if ((arg_conf == 0) || (arg_conf_len <= 0))
1006 log_fatal(
"Unable to send -F option fqdn.fqdn");
1008 free(last_arg_conf);
1013 if (arg_conf == 0) {
1014 arg_conf_len =
asprintf(&arg_conf,
"timeout %d;", timeout_arg);
1016 if ((arg_conf == 0) || (arg_conf_len <= 0))
1017 log_fatal(
"Unable to process --timeout timeout argument");
1019 char *last_arg_conf = arg_conf;
1021 arg_conf_len =
asprintf(&arg_conf,
"%s\ntimeout %d;", last_arg_conf, timeout_arg);
1023 if ((arg_conf == 0) || (arg_conf_len == 0))
1024 log_fatal(
"Unable to process --timeout timeout argument");
1026 free(last_arg_conf);
1030 if ((dhcp_vendor_class_identifier_arg != NULL) && (*dhcp_vendor_class_identifier_arg !=
'\0')) {
1031 if (arg_conf == 0) {
1032 arg_conf_len =
asprintf(&arg_conf,
"send vendor-class-identifier \"%s\";", dhcp_vendor_class_identifier_arg);
1034 if ((arg_conf == 0) || (arg_conf_len <= 0))
1035 log_fatal(
"Unable to send -V option vendor-class-identifier");
1037 char *last_arg_conf = arg_conf;
1039 arg_conf_len =
asprintf(&arg_conf,
"%s\nsend vendor-class-identifier \"%s\";", last_arg_conf, dhcp_vendor_class_identifier_arg);
1041 if ((arg_conf == 0) || (arg_conf_len <= 0))
1042 log_fatal(
"Unable to send -V option vendor-class-identifier");
1044 free(last_arg_conf);
1048 if (dhclient_request_options != NULL) {
1049 if (arg_conf == 0) {
1050 arg_conf_len =
asprintf(&arg_conf,
"request %s;", dhclient_request_options);
1052 if ((arg_conf == 0) || (arg_conf_len <= 0))
1053 log_fatal(
"Unable to parse --request-options <request options list> argument");
1055 char *last_arg_conf = arg_conf;
1057 arg_conf_len =
asprintf(&arg_conf,
"%s\nrequest %s;", last_arg_conf, dhclient_request_options);
1059 if ((arg_conf == 0) || (arg_conf_len <= 0))
1060 log_fatal(
"Unable to parse --request-options <request options list> argument");
1062 free(last_arg_conf);
1067 if (arg_conf_len == 0)
1068 if ((arg_conf_len = strlen(arg_conf)) == 0)
1070 log_fatal(
"Unable to process -C/-H/-F/--timeout/-V/--request-options configuration arguments");
1075 const char *val = NULL;
1078 status =
new_parse(&cfile, -1, arg_conf, arg_conf_len,
"extra dhclient -C/-H/-F/--timeout/-V/--request-options configuration arguments", 0);
1081 log_fatal(
"Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
1093 log_fatal(
"Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
1101 if (
ip->client->config->timeout == 60)
1102 ip->client->config->timeout = timeout_arg;
1150 log_info(
"No broadcast interfaces found - exiting.");
1153 }
else if (!release_mode && !exit_mode) {
1170 if (
ip->client->alias != NULL)
1187 unsigned backup_seed = 0;
1190 if (
ip -> hw_address.hlen <=
sizeof seed )
1193 &
ip -> hw_address.hbuf [
ip -> hw_address.hlen -
1194 sizeof seed],
sizeof seed);
1211#ifdef ISC_PATH_RANDOMDEV
1214 nrnd = fread(&seed,
sizeof(seed), 1, frnd);
1230 if (
ip -> hw_address.hlen <=
sizeof seed )
1233 &
ip->hw_address.hbuf[
ip->hw_address.hlen -
1234 sizeof seed],
sizeof seed);
1238 if ( seed_flag == 0 ) {
1239 if ( backup_seed != 0 ) {
1241 log_info (
"xid: rand init seed (0x%x) built using all"
1242 " available interfaces",seed);
1245 seed =
cur_time^((unsigned) gethostid()) ;
1246 log_info (
"xid: warning: no netdev with useable HWADDR found"
1247 " for seed's uniqueness enforcement");
1248 log_info (
"xid: rand init seed (0x%x) built using gethostid",
1254 seed += ((unsigned)(
cur_tv.tv_usec * 1000000)) + (
unsigned)getpid();
1262 setup_ib_interface(
ip);
1281#if defined(DHCPv6) && defined(DHCP4o6)
1283 dhcp4o6_setup(dhcp4o6_port);
1290 for (client =
ip->client ; client != NULL ;
1291 client = client->
next) {
1295 }
else if (exit_mode) {
1315 for (client =
ip->client ; client ;
1316 client = client->
next) {
1333 tv.tv_usec = random()
1369 log_fatal(
"Can't allocate new generic object: %s\n",
1370 isc_result_totext(result));
1376 log_fatal(
"Can't start OMAPI protocol: %s",
1377 isc_result_totext (result));
1386#if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
1387 defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1388 dmalloc_cutoff_generation = dmalloc_generation;
1389 dmalloc_longterm = dmalloc_outstanding;
1390 dmalloc_outstanding = 0;
1393#if defined(ENABLE_GENTLE_SHUTDOWN)
1430 isc_result_t result;
1439 usage(
"No interfaces available for stateless command: %s",
"-S");
1482 dhcp4o6_setup(port);
1503 log_fatal(
"Can't allocate new generic object: %s\n",
1504 isc_result_totext(result));
1510 log_fatal(
"Can't start OMAPI protocol: %s",
1511 isc_result_totext(result));
1517#if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
1518 defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1519 dmalloc_cutoff_generation = dmalloc_generation;
1520 dmalloc_longterm = dmalloc_outstanding;
1521 dmalloc_outstanding = 0;
1543 const char *s,
const char *
file,
int line)
1578 ip->client->config->bootp_broadcast_always = 1;
1584 for (g =
ip->client->config->on_transmission; g != NULL; g = g->
next) {
1587 "dhcp-client-identifier") == 0)) {
1593 log_fatal(
"dhcp-client-identifier must be specified for InfiniBand");
1630#if defined(DHCPv6) && defined(DHCP4o6)
1632 if (dhcp4o6_state < 0)
1643 client ->
active -> is_bootp ||
1657 client ->
xid = random ();
1712 uint32_t v6only_wait = 0;
1720 for (i = 0 ; req[i] != NULL ; i++) {
1742 if (
data.len == 4) {
1750 return (v6only_wait);
1771 uint32_t v6only_wait;
1788 (
long unsigned)v6only_wait);
1792 tv.tv_sec =
cur_tv.tv_sec + v6only_wait;
1793 tv.tv_usec =
cur_tv.tv_usec;
1825 for (lp = client -> offered_leases; lp; lp =
next) {
1834 picked ->
next = NULL;
1839 client -> offered_leases = NULL;
1846 client -> state =
S_INIT;
1853 client ->
new = picked;
1871 client -> first_sending =
cur_time;
1872 client -> interval = client -> config -> initial_interval;
1876 client -> xid = client ->
packet.xid;
1893 uint32_t v6only_wait;
1900 for (client =
ip -> client; client; client = client -> next) {
1901 if (client -> xid ==
packet -> raw -> xid)
1905 (
packet -> interface -> hw_address.hlen - 1 !=
1906 packet -> raw -> hlen) ||
1907 (memcmp (&
packet -> interface -> hw_address.hbuf [1],
1910 log_debug (
"DHCPACK in wrong transaction.");
1925 log_info (
"DHCPACK of %s from %s (xid=0x%x)",
1928 ntohl(client -> xid));
1932 if (v6only_wait > 0) {
1933 log_info(
"v6 only preferred for %lu seconds.",
1934 (
long unsigned)v6only_wait);
1942 log_info (
"packet_to_lease failed.");
1946 client ->
new =
lease;
1954 memset (&ds, 0,
sizeof ds);
1957 packet -> options, client ->
new -> options,
1962 client ->
new -> expiry = 0;
1965 client ->
new -> expiry = 0;
1970 log_error (
"no expiry time on offered lease.");
1976 tv.tv_sec =
cur_tv.tv_sec;
1977 tv.tv_usec =
cur_tv.tv_usec + 500000;
1979 if (tv.tv_usec >= 1000000) {
1981 tv.tv_usec -= 1000000;
2000 packet -> options, client ->
new -> options,
2005 client ->
new -> renewal = 0;
2008 client ->
new -> renewal = 0;
2011 if (!client ->
new -> renewal)
2012 client ->
new -> renewal = client ->
new -> expiry / 2 + 1;
2014 if (client ->
new -> renewal <= 0)
2015 client ->
new -> renewal =
TIME_MAX;
2020 (((random() % client->
new->
renewal) + 3) / 4);
2027 packet -> options, client ->
new -> options,
2032 client ->
new -> rebind = 0;
2035 client ->
new -> rebind = 0;
2037 if (client ->
new -> rebind <= 0) {
2038 if (client ->
new -> expiry <=
TIME_MAX / 7)
2039 client ->
new -> rebind =
2040 client ->
new -> expiry * 7 / 8;
2042 client ->
new -> rebind =
2043 client ->
new -> expiry / 8 * 7;
2048 if (client ->
new -> renewal > client ->
new -> rebind) {
2049 if (client ->
new -> rebind <=
TIME_MAX / 3)
2050 client ->
new -> renewal =
2051 client ->
new -> rebind * 3 / 4;
2053 client ->
new -> renewal =
2054 client ->
new -> rebind / 4 * 3;
2057 client ->
new -> expiry +=
cur_time;
2059 if (client ->
new -> expiry <
cur_time)
2060 client ->
new -> expiry =
TIME_MAX;
2061 client ->
new -> renewal +=
cur_time;
2062 if (client ->
new -> renewal <
cur_time)
2063 client ->
new -> renewal =
TIME_MAX;
2064 client ->
new -> rebind +=
cur_time;
2065 if (client ->
new -> rebind <
cur_time)
2066 client ->
new -> rebind =
TIME_MAX;
2105 log_info(
"Unable to obtain a lease on first "
2106 "try (declined). Exiting.");
2109#if defined (CALL_SCRIPT_ON_ONETRY_FAIL)
2118 tv.tv_usec =
cur_tv.tv_usec;
2146 random() % 1000000 :
cur_tv.tv_usec;
2149 log_info(
"bound to %s -- renewal in %ld seconds.",
2155#if defined (NSUPDATE)
2178 client -> xid = client ->
packet.xid;
2180 memset (&ds, 0,
sizeof ds);
2186 client -> active -> options,
2189 memcpy (client -> destination.iabuf, ds.
data, 4);
2190 client -> destination.len = 4;
2198 client -> first_sending =
cur_time;
2199 client -> interval = client -> config -> initial_interval;
2268 for (ap =
packet -> interface -> client -> config -> reject_list;
2269 ap; ap = ap ->
next) {
2278 log_info(
"BOOTREPLY from %s rejected by rule %s "
2293 void (*handler) (
struct packet *);
2321 ap; ap = ap -> next) {
2330 log_info(
"%s from %s rejected by rule %s mask %s.",
2344 char addrbuf[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")];
2352 ap ; ap = ap->
next) {
2355 log_info(
"%s from %s rejected by rule %s",
2368 log_info(
"RCV: %s message on %s from %s.",
2372 forw_dhcpv4_response(
packet);
2382 log_info(
"RCV: %s message on %s from %s.",
2393 client = client->
next) {
2402 log_info(
"Packet received, but nothing done with it.");
2428 if (dhcp4o6_state == -1) {
2429 log_info(
"forw_dhcpv4_response: not ready.");
2434 log_error(
"forw_dhcpv4_response: bad address");
2443 log_info(
"DHCPv4-response from %s missing "
2444 "DHCPv4 Message option.",
2449 memset(&enc_opt_data, 0,
sizeof(enc_opt_data));
2452 log_error(
"forw_dhcpv4_response: error evaluating "
2460 "no memory for encapsulated packet.");
2468 memset(&ds, 0,
sizeof(ds));
2470 log_error(
"forw_dhcpv4_response: no memory buffer.");
2474 ds.data = ds.buffer->data;
2475 ds.len = enc_opt_data.len + 16;
2476 memcpy(ds.buffer->data, enc_opt_data.data, enc_opt_data.len);
2477 memcpy(ds.buffer->data + enc_opt_data.len,
2484 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
2486 log_error(
"forw_dhcpv4_response: send(): %m");
2500static void recv_dhcpv4_response(
struct data_string *raw)
2506 log_error(
"recv_dhcpv4_response: no interfaces.");
2511 memcpy(from.iabuf, raw->
data + (raw->
len - 16), 16);
2518 log_error(
"recv_dhcpv4_response: no memory for packet.");
2530 log_error(
"recv_dhcpv4_response: no memory for options.");
2551 memset(&dp, 0,
sizeof dp);
2581 uint32_t v6only_wait;
2586 const char *
name =
packet -> packet_type ?
"DHCPOFFER" :
"BOOTREPLY";
2595 for (client =
ip -> client; client; client = client -> next)
2596 if (client -> xid ==
packet -> raw -> xid)
2603 (
packet -> interface -> hw_address.hlen - 1 !=
2604 packet -> raw -> hlen) ||
2605 (memcmp (&
packet -> interface -> hw_address.hbuf [1],
2608 log_debug (
"%s in wrong transaction.", name);
2613 sprintf (obuf,
"%s of %s from %s", name,
2619 if (v6only_wait > 0) {
2620 log_info(
"%s: v6 only preferred for %lu.", obuf,
2621 (
long unsigned)v6only_wait);
2632 for (i = 0 ; req[i] != NULL ; i++) {
2639 option_code_hash_lookup(&
option,
2644 log_info(
"%s: no %s option.", obuf,
2647 log_info(
"%s: no unknown-%u option.",
2659 if (
lease -> address.len ==
sizeof packet -> raw -> yiaddr &&
2660 !memcmp (
lease -> address.iabuf,
2661 &
packet -> raw -> yiaddr,
lease -> address.len)) {
2669 log_info (
"%s: packet_to_lease failed.", obuf);
2678 if (!
packet -> options_valid || !
packet -> packet_type)
2679 lease -> is_bootp = 1;
2682 lease -> medium = client -> medium;
2685 stop_selecting = (client -> first_sending +
2686 client -> config -> select_interval);
2690 if (
lease -> address.len == client -> requested_address.len &&
2691 !memcmp (
lease -> address.iabuf,
2692 client -> requested_address.iabuf,
2693 client -> requested_address.len)) {
2694 lease -> next = client -> offered_leases;
2695 client -> offered_leases =
lease;
2699 if (!client -> offered_leases)
2700 client -> offered_leases =
lease;
2702 for (lp = client -> offered_leases; lp ->
next;
2712 if (stop_selecting <=
cur_tv.tv_sec)
2715 tv.tv_sec = stop_selecting;
2716 tv.tv_usec =
cur_tv.tv_usec;
2738 log_error(
"packet_to_lease: no memory to record lease.\n");
2749 lease->address.len);
2753 lease->next_srv_addr.len);
2755 memset(&data, 0,
sizeof(data));
2757 if (client -> config -> vendor_space_name) {
2763 client -> config -> vendor_space_name &&
2765 (
struct lease *)0, client,
2769 if (!option_code_hash_lookup(&
option,
2773 "option (%s:%d).",
MDL);
2777 client -> config -> vendor_space_name
2803 if (!(i & 2) &&
packet -> raw -> sname [0]) {
2807 if (!
packet -> raw -> sname [len])
2811 log_error (
"dhcpoffer: no memory for server name.\n");
2816 packet -> raw -> sname, len);
2830 log_error (
"dhcpoffer: no memory for filename.\n");
2855 for (client =
ip -> client; client; client = client ->
next)
2863 packet -> raw -> hlen) ||
2867 log_debug (
"DHCPNAK in wrong transaction.");
2886 log_info (
"DHCPNAK with no active lease.\n");
2919 client -> state =
S_INIT;
2938 interval =
cur_time - client -> first_sending;
2942 if (interval > client -> config ->
timeout) {
2950 if (!client -> offered_leases &&
2951 client -> config -> media) {
2954 if (client -> medium) {
2955 client -> medium = client -> medium -> next;
2958 if (!client -> medium) {
2960 log_fatal (
"No valid media types for %s!",
2961 client -> interface -> name);
2963 client -> config -> media;
2967 log_info (
"Trying medium \"%s\" %d",
2968 client -> medium ->
string, increase);
2996 if (
cur_time + client -> interval >
2997 client -> first_sending + client -> config ->
timeout)
2998 client -> interval =
2999 (client -> first_sending +
3003 if (interval < 65536)
3004 client ->
packet.secs = htons (interval);
3006 client ->
packet.secs = htons (65535);
3007 client -> secs = client ->
packet.secs;
3009#if defined(DHCPv6) && defined(DHCP4o6)
3011 log_info (
"DHCPDISCOVER interval %ld",
3012 (
long)(client -> interval));
3015 log_info (
"DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
3016 client -> name ? client -> name : client -> interface -> name,
3018 ntohs (
sockaddr_broadcast.sin_port), (
long)(client -> interval), ntohl(client -> xid));
3021#if defined(DHCPv6) && defined(DHCP4o6)
3023 result = send_dhcpv4_query(client, 1);
3030#if defined(DHCPv6) && defined(DHCP4o6)
3032 log_error(
"%s:%d: Failed to send %d byte long packet.",
3036 log_error(
"%s:%d: Failed to send %d byte long packet over %s "
3048 tv.tv_usec = client->
interval > 1 ? random() % 1000000 :
cur_tv.tv_usec;
3068 if (!lease_list || !
lease) {
3073 for (cur = *lease_list; cur; cur =
next) {
3078 lease->address.len))) {
3107 if (!lease_list || !
lease) {
3119 for (tail = *lease_list; tail && tail->
next; tail = tail->
next){};
3126 *lease_list =
lease;
3137 log_debug (
"%s: %p addr:%s expires:%ld :is_static? %d",
3158 loop = lp = client -> active;
3160 log_info (
"No DHCPOFFERS received.");
3164 if (!client -> active && client -> leases)
3168 while (client -> active) {
3169 if (client -> active -> expiry >
cur_time) {
3171 (client -> active -> is_static
3172 ?
"fallback" :
"recorded"),
3173 piaddr (client -> active -> address));
3177 client -> active -> medium);
3180 if (client -> alias)
3190 log_info (
"bound: renewal in %ld %s.",
3191 (
long)(client -> active -> renewal -
3196 random() % 1000000 :
3201 log_info (
"bound: immediate renewal.");
3211 if (!client -> leases) {
3212 client -> leases = client -> active;
3222 client -> active = client -> leases;
3223 client -> leases = client -> leases ->
next;
3228 if (client -> active == loop)
3231 loop = client -> active;
3239 log_info (
"Unable to obtain a lease on first try.%s",
3243#if defined (CALL_SCRIPT_ON_ONETRY_FAIL)
3251 log_info (
"No working leases in persistent database - sleeping.");
3253 if (client -> alias)
3256 client -> state =
S_INIT;
3259 tv.tv_usec = ((tv.tv_sec -
cur_tv.tv_sec) > 1) ?
3260 random() % 1000000 :
cur_tv.tv_usec;
3272 struct sockaddr_in destination;
3273 struct in_addr from;
3276 const char* rip_str =
"";
3279 interval =
cur_time - client -> first_sending;
3293 interval > client -> config -> reboot_timeout) {
3295 client -> state =
S_INIT;
3304 !client -> medium &&
3305 client -> active -> medium ) {
3306 script_init(client,
"MEDIUM", client -> active -> medium);
3313 client -> medium = client -> active -> medium;
3319 cur_time > client -> active -> expiry) {
3324 if (client -> alias)
3332 if (client -> alias)
3337 client -> state =
S_INIT;
3343 if (!client -> interval)
3344 client -> interval = client -> config -> initial_interval;
3346 client -> interval += ((random () >> 2) %
3347 (2 * client -> interval));
3351 if (client -> interval >
3352 client -> config -> backoff_cutoff)
3353 client -> interval =
3354 ((client -> config -> backoff_cutoff / 2)
3355 + ((random () >> 2) %
3356 client -> config -> backoff_cutoff));
3361 cur_time + client -> interval > client -> active -> expiry)
3362 client -> interval =
3363 client -> active -> expiry -
cur_time + 1;
3369 cur_time > client -> active -> rebind)
3372 memcpy (&destination.sin_addr.s_addr,
3373 client -> destination.iabuf,
3374 sizeof destination.sin_addr.s_addr);
3376 destination.sin_family = AF_INET;
3378 destination.sin_len =
sizeof destination;
3383 memcpy (&from, client -> active -> address.iabuf,
3386 from.s_addr = INADDR_ANY;
3390 client ->
packet.secs = client -> secs;
3392 if (interval < 65536)
3393 client ->
packet.secs = htons (interval);
3395 client ->
packet.secs = htons (65535);
3398#if defined(DHCPv6) && defined(DHCP4o6)
3403 memset(rip_buf, 0x0,
sizeof(rip_buf));
3411 strncpy(rip_buf, rip_str,
sizeof(rip_buf)-1);
3412 log_info (
"DHCPREQUEST for %s on %s to %s port %d (xid=0x%x)",
3415 inet_ntoa(destination.sin_addr),
3416 ntohs (destination.sin_port),
3417 ntohl(client -> xid));
3419#if defined(DHCPv6) && defined(DHCP4o6)
3422 if (destination.sin_addr.s_addr == INADDR_BROADCAST)
3424 result = send_dhcpv4_query(client, broadcast);
3426 log_error(
"%s:%d: Failed to send %d byte long packet.",
3431 if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
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:"
3464 log_error(
"%s:%d: Failed to send %d byte long packet"
3465 " over %s interface.",
MDL,
3472 tv.tv_usec = ((tv.tv_sec -
cur_tv.tv_sec) > 1) ?
3473 random() % 1000000 :
cur_tv.tv_usec;
3484#if defined(DHCPv6) && defined(DHCP4o6)
3489 log_info (
"DHCPDECLINE of %s on %s to %s port %d (xid=0x%x)",
3494 ntohl(client ->
xid));
3498#if defined(DHCPv6) && defined(DHCP4o6)
3500 result = send_dhcpv4_query(client, 1);
3507#if defined(DHCPv6) && defined(DHCP4o6)
3509 log_error(
"%s:%d: Failed to send %d byte long packet.",
3513 log_error(
"%s:%d: Failed to send %d byte long packet over %s"
3525 struct sockaddr_in destination;
3526 struct in_addr from;
3528 memcpy (&from, client -> active -> address.iabuf,
3530 memcpy (&destination.sin_addr.s_addr,
3531 client -> destination.iabuf,
3532 sizeof destination.sin_addr.s_addr);
3534 destination.sin_family = AF_INET;
3536 destination.sin_len =
sizeof destination;
3541 client -> active -> expiry =
3542 client -> active -> renewal =
3543 client -> active -> rebind =
cur_time;
3545 log_error (
"Can't release lease: lease write failed.");
3549#if defined(DHCPv6) && defined(DHCP4o6)
3554 log_info (
"DHCPRELEASE of %s on %s to %s port %d (xid=0x%x)",
3557 inet_ntoa (destination.sin_addr),
3558 ntohs (destination.sin_port),
3559 ntohl(client -> xid));
3561#if defined(DHCPv6) && defined(DHCP4o6)
3564 if (destination.sin_addr.s_addr == INADDR_BROADCAST)
3566 result = send_dhcpv4_query(client, broadcast);
3568 log_error(
"%s:%d: Failed to send %d byte long packet.",
3574#if defined(SO_BINDTODEVICE)
3578 log_error(
"%s:%d: Failed to bind fallback interface"
3586 log_error(
"%s:%d: Failed to send %d byte long packet"
3587 " over %s interface.",
MDL,
3591#if defined(SO_BINDTODEVICE)
3593 SO_BINDTODEVICE, NULL, 0) < 0) {
3594 log_fatal(
"%s:%d: Failed to unbind fallback interface:"
3604 log_error (
"%s:%d: Failed to send %d byte long packet"
3605 " over %s interface.",
MDL,
3613#if defined(DHCPv6) && defined(DHCP4o6)
3625static int send_dhcpv4_query(
struct client_state *client,
int broadcast) {
3630 if (dhcp4o6_state <= 0) {
3631 log_info(
"send_dhcpv4_query: not ready.");
3641 memset(&ds, 0,
sizeof(ds));
3643 log_error(
"Unable to allocate memory for DHCPv4-query.");
3646 ds.data = ds.buffer->data;
3671 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
3673 log_error(
"send_dhcpv4_query: send(): %m");
3686static void forw_dhcpv4_query(
struct data_string *raw) {
3692 struct sockaddr_in6 sin6;
3693 int i, send_ret, attempt, success;
3695 attempt = success = 0;
3696 memset(&sin6, 0,
sizeof(sin6));
3697 sin6.sin6_family = AF_INET6;
3700 sin6.sin6_len =
sizeof(sin6);
3702 memset(&addrs, 0,
sizeof(addrs));
3704 for (client =
ip->client; client != NULL;
3705 client = client->
next) {
3718 lease->options, NULL,
3720 ((addrs.len %
sizeof(sin6.sin6_addr)) != 0)) {
3724 if (addrs.len == 0) {
3732 if (send_ret == raw->
len)
3736 for (i = 0; i < addrs.len;
3737 i +=
sizeof(sin6.sin6_addr)) {
3738 memcpy(&sin6.sin6_addr, addrs.data + i,
3739 sizeof(sin6.sin6_addr));
3743 if (send_ret == raw->
len)
3750 log_info(
"forw_dhcpv4_query: sent(%d): %d/%d",
3751 raw->
len, success, attempt);
3767 struct buffer *bp = NULL;
3790 log_error (
"can't make requested address cache.");
3816 for (i = 0 ; prl[i] != NULL ; i++)
3821 log_error(
"can't make parameter list buffer.");
3826 for (i = 0 ; prl[i] != NULL ; i++)
3830 if (!(option_code_hash_lookup(&
option,
3855 memset(&client_identifier, 0,
sizeof(client_identifier));
3858 client_identifier.
len,
MDL))
3859 log_fatal(
"no memory for default DUID!");
3877 memcpy(client_identifier.
buffer->
data + 5 - hw_len,
3882 memcpy(client_identifier.
buffer->
data + (1 + 4),
3889 (u_int8_t *)client_identifier.
data,
3890 client_identifier.
len,
3892 log_error (
"can't make requested client id cache..");
3916 memset (&client ->
packet, 0,
sizeof (client ->
packet));
3921 client -> config -> requested_options,
3925 client -> packet_length =
3927 (
struct lease *)0, client,
3936 client -> config -> vendor_space_name);
3943 client ->
packet.htype = client ->
interface -> hw_address.hbuf [0];
3945 client ->
packet.hlen = client ->
interface -> hw_address.hlen - 1;
3946 client ->
packet.hops = 0;
3947 client ->
packet.xid = random ();
3948 client ->
packet.secs = 0;
3952 client ->
packet.flags = 0;
3956 memset (&(client ->
packet.ciaddr),
3957 0,
sizeof client ->
packet.ciaddr);
3958 memset (&(client ->
packet.yiaddr),
3959 0,
sizeof client ->
packet.yiaddr);
3960 memset (&(client ->
packet.siaddr),
3961 0,
sizeof client ->
packet.siaddr);
3963 if (client -> interface -> hw_address.hlen > 0)
3964 memcpy (client ->
packet.chaddr,
3965 &client -> interface -> hw_address.hbuf [1],
3966 (
unsigned)(client -> interface -> hw_address.hlen - 1));
3969 dump_raw ((
unsigned char *)&client ->
packet, client -> packet_length);
3981 memset (&client ->
packet, 0,
sizeof (client ->
packet));
3989 if (client -> sent_options)
3996 : (
struct iaddr *)0),
3997 client -> config -> requested_options,
3998 &client -> sent_options);
4001 client -> packet_length =
4003 (
struct lease *)0, client,
4006 client -> sent_options,
4012 client -> config -> vendor_space_name);
4018 client ->
packet.htype = client ->
interface -> hw_address.hbuf [0];
4020 client ->
packet.hlen = client ->
interface -> hw_address.hlen - 1;
4021 client ->
packet.hops = 0;
4022 client ->
packet.xid = client -> xid;
4023 client ->
packet.secs = 0;
4027 if (client -> state ==
S_BOUND ||
4030 memcpy (&client ->
packet.ciaddr,
4031 lease -> address.iabuf,
lease -> address.len);
4032 client ->
packet.flags = 0;
4034 memset (&client ->
packet.ciaddr, 0,
4035 sizeof client ->
packet.ciaddr);
4037 client ->config->bootp_broadcast_always)) &&
4039 client ->
packet.flags = 0;
4044 memset (&client ->
packet.yiaddr, 0,
4045 sizeof client ->
packet.yiaddr);
4046 memset (&client ->
packet.siaddr, 0,
4047 sizeof client ->
packet.siaddr);
4048 if (client -> state !=
S_BOUND &&
4052 memset (&client ->
packet.giaddr, 0,
4053 sizeof client ->
packet.giaddr);
4054 if (client -> interface -> hw_address.hlen > 0)
4055 memcpy (client ->
packet.chaddr,
4056 &client -> interface -> hw_address.hbuf [1],
4057 (
unsigned)(client -> interface -> hw_address.hlen - 1));
4060 dump_raw ((
unsigned char *)&client ->
packet, client -> packet_length);
4080 memset (&client ->
packet, 0,
sizeof (client ->
packet));
4081 client -> packet_length =
4083 (
struct lease *)0, client, 0,
4086 client -> config -> vendor_space_name);
4095 client ->
packet.htype = client ->
interface -> hw_address.hbuf [0];
4097 client ->
packet.hlen = client ->
interface -> hw_address.hlen - 1;
4098 client ->
packet.hops = 0;
4099 client ->
packet.xid = client -> xid;
4100 client ->
packet.secs = 0;
4103 client ->
packet.flags = 0;
4108 memset (&client ->
packet.ciaddr, 0,
4109 sizeof client ->
packet.ciaddr);
4110 memset (&client ->
packet.yiaddr, 0,
4111 sizeof client ->
packet.yiaddr);
4112 memset (&client ->
packet.siaddr, 0,
4113 sizeof client ->
packet.siaddr);
4115 memcpy (client ->
packet.chaddr,
4116 &client -> interface -> hw_address.hbuf [1],
4117 client -> interface -> hw_address.hlen);
4120 dump_raw ((
unsigned char *)&client ->
packet, client -> packet_length);
4133 memset (&client ->
packet, 0,
sizeof (client ->
packet));
4140 client -> packet_length =
4142 (
struct lease *)0, client,
4151 client -> config -> vendor_space_name);
4158 client ->
packet.htype = client ->
interface -> hw_address.hbuf [0];
4160 client ->
packet.hlen = client ->
interface -> hw_address.hlen - 1;
4161 client ->
packet.hops = 0;
4162 client ->
packet.xid = random ();
4163 client ->
packet.secs = 0;
4164 client ->
packet.flags = 0;
4165 memcpy (&client ->
packet.ciaddr,
4166 lease -> address.iabuf,
lease -> address.len);
4167 memset (&client ->
packet.yiaddr, 0,
4168 sizeof client ->
packet.yiaddr);
4169 memset (&client ->
packet.siaddr, 0,
4170 sizeof client ->
packet.siaddr);
4172 memcpy (client ->
packet.chaddr,
4173 &client -> interface -> hw_address.hbuf [1],
4174 client -> interface -> hw_address.hlen);
4177 dump_raw ((
unsigned char *)&client ->
packet, client -> packet_length);
4216 for (client =
ip -> client; client; client = client ->
next) {
4217 for (lp = client -> leases; lp; lp = lp ->
next) {
4220 if (client -> active)
4222 client -> active, 1, 0);
4237 for (client =
ip -> client; client; client = client ->
next) {
4238 for (lp = client -> leases; lp; lp = lp ->
next) {
4241 if (client -> active)
4243 client -> active, 1, 0);
4265 const char *name, *dot;
4267 char *preamble = stuff;
4269 memset (&ds, 0,
sizeof ds);
4279 in_options, cfg_options, scope, oc,
MDL)) {
4281 fprintf(
leaseFile,
"%soption %s%s%s", preamble,
4302 const char *preamble)
4315 if (c >=
'0' && c <=
'9')
4318 if (c >=
'a' && c <=
'f')
4319 return c -
'a' + 10;
4321 if (c >=
'A' && c <=
'F')
4322 return c -
'A' + 10;
4329 const char *id_fname =
"/etc/machine-id";
4332 FILE *
file = fopen( id_fname ,
"r");
4335 return ISC_R_IOERROR;
4337 nread = fread(
id, 1,
sizeof id,
file);
4341 log_debug(
"Not enough data in %s", id_fname);
4342 return ISC_R_IOERROR;
4345 for (j = 0; j < 16; j++) {
4351 if (a < 0 || b < 0) {
4352 log_debug(
"Wrong data in %s", id_fname);
4353 return ISC_R_IOERROR;
4355 uuid[j] = a << 4 | b;
4359 uuid[6] = (uuid[6] & 0x0F) | 0x40;
4361 uuid[8] = (uuid[8] & 0x3F) | 0x80;
4396 log_debug(
"Cannot form default DUID from interface %s.",
ip->name);
4400 return ISC_R_UNEXPECTED;
4403 if ((
ip->hw_address.hlen == 0) ||
4404 (
ip->hw_address.hlen >
sizeof(
ip->hw_address.hbuf)))
4405 log_fatal(
"Impossible hardware address length at %s:%d.",
MDL);
4415 len = 2 +
sizeof (uuid);
4424 len = 4 + (
ip->hw_address.hlen - 1);
4429 log_fatal(
"no memory for default DUID!");
4435 memcpy(duid->
buffer->
data + 2, uuid,
sizeof(uuid));
4442 memcpy(duid->
buffer->
data + 8,
ip->hw_address.hbuf + 1,
4443 ip->hw_address.hlen - 1);
4447 memcpy(duid->
buffer->
data + 4,
ip->hw_address.hbuf + 1,
4448 ip->hw_address.hlen - 1);
4455 log_info(
"form_duid: Couldn't allocate memory to log duid!");
4471 if ((duid == NULL) || (duid->
len <= 2))
4478 return ISC_R_IOERROR;
4486 return ISC_R_NOMEMORY;
4488 stat = fprintf(
leaseFile,
"default-duid %s;\n", str);
4491 return ISC_R_IOERROR;
4494 return ISC_R_IOERROR;
4502 int rewrite,
int sync)
4516 if (client == NULL ||
lease == NULL)
4523 return ISC_R_IOERROR;
4527 stat = fprintf(
leaseFile,
"lease6 {\n");
4529 return ISC_R_IOERROR;
4531 stat = fprintf(
leaseFile,
" interface \"%s\";\n",
4534 return ISC_R_IOERROR;
4536 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
4557 (
const unsigned char *) &ia->
iaid, 4,
4562 return ISC_R_IOERROR;
4573 stat = fprintf(
leaseFile,
" %s %s {\n", ianame,
4579 return ISC_R_IOERROR;
4582 stat = fprintf(
leaseFile,
" starts %d;\n"
4587 stat = fprintf(
leaseFile,
" starts %d;\n",
4590 return ISC_R_IOERROR;
4592 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4599 " iaprefix %s/%d {\n",
4603 return ISC_R_IOERROR;
4605 stat = fprintf(
leaseFile,
" starts %d;\n"
4606 " preferred-life %u;\n"
4611 return ISC_R_IOERROR;
4614 write_options(client, addr->
options,
" ");
4618 return ISC_R_IOERROR;
4622 write_options(client, ia->
options,
" ");
4626 return ISC_R_IOERROR;
4629 if (
lease->released) {
4630 stat = fprintf(
leaseFile,
" released;\n");
4632 return ISC_R_IOERROR;
4635 if (
lease->options != NULL)
4636 write_options(client,
lease->options,
" ");
4640 return ISC_R_IOERROR;
4643 return ISC_R_IOERROR;
4647 log_error(
"write_client_lease: fsync(): %m");
4648 return ISC_R_IOERROR;
4675 if (
lease -> is_static)
4688 if (
lease -> is_bootp) {
4695 fprintf (
leaseFile,
" interface \"%s\";\n",
4696 client -> interface -> name);
4701 if (client -> name) {
4702 fprintf (
leaseFile,
" name \"%s\";\n", client -> name);
4708 fprintf (
leaseFile,
" fixed-address %s;\n",
4714 if (
lease -> filename) {
4717 fprintf (
leaseFile,
" filename \"%s\";\n", s);
4727 if (
lease->server_name != NULL) {
4730 fprintf(
leaseFile,
" server-name \"%s\";\n", s);
4739 if (
lease -> medium) {
4742 fprintf (
leaseFile,
" medium \"%s\";\n", s);
4756 memset (&ds, 0,
sizeof ds);
4758 write_options(client,
lease->options,
" ");
4762 fprintf(
leaseFile,
" renew %s\n", tval) < 0)
4767 fprintf(
leaseFile,
" rebind %s\n", tval) < 0)
4772 fprintf(
leaseFile,
" expire %s\n", tval) < 0)
4783 if (!errors && makesure) {
4785 log_info (
"write_client_lease: %m");
4790 return errors ? 0 : 1;
4817 for (sl = client -> env; sl; sl =
next) {
4824 if (client -> interface) {
4826 client -> interface -> name);
4830 "",
"client",
"%s", client -> name);
4833 "",
"medium",
"%s", medium ->
string);
4836 client_envadd (client,
"",
"pid",
"%ld", (
long int)getpid ());
4839 (
long int)dad_wait_time);
4857 in_options, cfg_options, scope, oc,
MDL)) {
4867 length = strlen(
value);
4871 value, length) == 0) {
4876 "option - discarded",
4921 if (
lease->next_srv_addr.len != 0) {
4933 memset (&data, 0,
sizeof data);
4964 (&data, (
struct packet *)0,
4965 (
struct lease *)0, client,
4970 if (broadcast.
len) {
4972 prefix,
"broadcast_address",
4973 "%s",
piaddr (broadcast));
4981 if (
lease->filename) {
4984 strlen(
lease->filename)) == 0) {
4986 "%s",
lease->filename);
4989 "option - discarded",
4994 if (
lease->server_name) {
4997 strlen(
lease->server_name)) == 0 ) {
4999 "%s",
lease->server_name);
5002 "option - discarded",
5003 lease->server_name);
5016 (
unsigned long)(
lease -> expiry));
5038 for (i = 0 ; req[i] != NULL ; i++) {
5063 char reason [] =
"REASON=NBI";
5064 static char client_path [] = CLIENT_PATH;
5067 int pid, wpid, wstatus;
5070 scriptName = client -> config -> script_name;
5074 envp =
dmalloc (((client ? client -> envc : 2) +
5077 log_error (
"No memory for client script environment.");
5084 envp [i++] = sp ->
string;
5088 for (sp = client -> env; sp; sp = sp ->
next) {
5089 envp [i++] = sp ->
string;
5092 envp [i++] = reason;
5095 envp [i++] = client_path;
5096 envp [i] = (
char *)0;
5099 argv [1] = (
char *)0;
5107 wpid = wait (&wstatus);
5108 }
while (wpid != pid && wpid > 0);
5125 for (sp = client -> env; sp; sp =
next) {
5133 gettimeofday(&
cur_tv, NULL);
5135 if (!WIFEXITED(wstatus)) {
5136 int sigval = WTERMSIG(wstatus);
5141 return (WEXITSTATUS(wstatus));
5145 const char *prefix,
const char *name,
const char *fmt, ...)
5153 va_start (list, fmt);
5154 len = vsnprintf (spbuf,
sizeof spbuf, fmt, list);
5157 val =
dmalloc (strlen (prefix) + strlen (name) + 1 +
5158 len +
sizeof *val,
MDL);
5160 log_error (
"client_envadd: cannot allocate space for variable");
5169 if (len >=
sizeof spbuf) {
5170 va_start (list, fmt);
5171 vsnprintf (s, len + 1, fmt, list);
5177 val ->
next = client -> env;
5178 client -> env = val;
5201 if (j + 1 == buflen)
5211 if (j + 1 == buflen)
5226 if (write(
dfd[1], &ret, 1) != 1)
5228 (void) close(
dfd[1]);
5244 if (
dfd[0] == -1 ||
dfd[1] == -1)
5248 if (write(
dfd[1], &buf, 1) != 1)
5250 (void) close(
dfd[1]);
5265 (void) open(
"/dev/null", O_RDWR | O_CLOEXEC);
5266 (void) open(
"/dev/null", O_RDWR | O_CLOEXEC);
5267 (void) open(
"/dev/null", O_RDWR | O_CLOEXEC);
5285 pfdesc = open (
path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
5292 pf = fdopen (pfdesc,
"we");
5297 fprintf (pf,
"%ld\n", (
long)getpid ());
5308 for (client =
ip -> client; client; client = client ->
next) {
5309 switch (client ->
state) {
5343#if defined(DHCPv6) && defined(DHCP4o6)
5345 if (dhcp4o6_state < 0)
5353 client -> xid = random ();
5356 if (client -> active) {
5361 memset (&ds, 0,
sizeof ds);
5363 client -> active -> options,
5367 (
struct lease *)0, client,
5369 client -> active -> options,
5372 memcpy (client -> destination.iabuf,
5374 client -> destination.len = 4;
5381 client -> first_sending =
cur_time;
5382 client -> interval = client -> config -> initial_interval;
5393 if (client -> alias)
5410#if defined(DHCPv6) && defined(DHCP4o6)
5433 interface_reference (&
ip, last ->
next,
MDL);
5434 interface_dereference (&last ->
next,
MDL);
5436 interface_reference (&last ->
next,
5438 interface_dereference (&
ip ->
next,
5443 interface_reference (&
ip,
5449 interface_dereference (&
ip ->
next,
5456 tmp ->
client ->
interface = tmp;
5458 interface_dereference (&
ip,
MDL);
5507 for (client =
ip->client ; client ; client = client->
next) {
5538static void shutdown_exit (
void *foo)
5546#if defined (NSUPDATE)
5563 isc_result_t eresult)
5566 isc_result_t result;
5580 dhclient_ddns_cb_free(ddns_cb,
MDL);
5589 isc_result_t result;
5592 if (client->
ddns_cb != NULL) {
5598 if (ddns_cb != NULL) {
5604 ddns_cb->
cur_func = client_dns_remove_action;
5608 if (result != ISC_R_TIMEDOUT) {
5609 dhclient_ddns_cb_free(ddns_cb,
MDL);
5630 log_info(
"Received signal %d, initiating shutdown.",
5639 for (client =
ip -> client; client; client = client -> next) {
5648 if (client -> active &&
5649 client -> active -> expiry >
cur_time) {
5650#if defined (NSUPDATE)
5679 tv.tv_sec =
cur_tv.tv_sec;
5680 tv.tv_usec =
cur_tv.tv_usec + 1;
5686#if defined (NSUPDATE)
5697 isc_result_t status = ISC_R_FAILURE;
5699 if ((client != NULL) &&
5700 ((client->
active != NULL) ||
5713 if (status != ISC_R_TIMEDOUT) {
5749 isc_result_t eresult)
5751 isc_result_t result;
5768 ddns_cb->
cur_func = client_dns_update_action;
5777 case ISC_R_TIMEDOUT:
5785 if (ddns_cb->
zone != NULL) {
5791 ddns_cb->
cur_func = client_dns_update_action;
5797 tv.tv_usec =
cur_tv.tv_usec;
5799 ddns_cb, NULL, NULL);
5803 dhclient_ddns_cb_free(ddns_cb,
MDL);
5821 if (!client -> sent_options)
5832 (
struct lease *)0, client,
5833 client -> sent_options,
5843 (
struct lease *)0, client,
5844 client -> sent_options,
5853 (
struct lease *)0, client,
5854 client -> sent_options,
5869 memset(&client_identifier, 0,
sizeof(client_identifier));
5893 client_identifier.data,
5894 client_identifier.len);
5912 (client_identifier.data[0] == 255)) {
5917 if (client_identifier.len <= 5)
5918 log_fatal(
"Impossible condition at %s:%d.",
5921 client_identifier.data + 5,
5922 client_identifier.len - 5);
5924 result =
get_dhcid(ddns_cb, ddns_v4_type,
5925 client_identifier.data,
5926 client_identifier.len);
5945 rcode = ISC_R_FAILURE;
5952 rcode = ISC_R_TIMEDOUT;
5975 if (client->
ddns_cb != NULL) {
5982 if (ddns_cb != NULL) {
5983 ddns_cb->
lease = (
void *)client;
5996 ddns_cb->
cur_func = client_dns_update_action;
6000 tv.tv_sec =
cur_tv.tv_sec + offset;
6001 tv.tv_usec =
cur_tv.tv_usec;
6003 ddns_cb, NULL, NULL);
6005 log_error(
"Unable to allocate dns update state for %s",
6014 struct servent *ent;
6028 ent = getservbyname(
"dhcpc",
"udp");
6030 ent = getservbyname(
"bootpc",
"udp");
6059static int check_domain_name(
const char *ptr,
size_t len,
int dots)
6064 if ((len == 0) || (len > 256))
6069 for (p=ptr; (*p != 0) && (len-- > 0); p++) {
6070 if ((*p ==
'-') || (*p ==
'_')) {
6072 if (((p - ptr) == 0) || (len == 0) || (p[1] ==
'.'))
6074 }
else if (*p ==
'.') {
6078 if ((d <= 0) || (d >= 64))
6081 if ((dots > 0) && (len > 0))
6083 }
else if (isalnum((
unsigned char)*p) == 0) {
6088 return(dots ? -1 : 0);
6091static int check_domain_name_list(
const char *ptr,
size_t len,
int dots)
6096 if ((ptr == NULL) || (len == 0))
6099 for (p=ptr; (*p != 0) && (len > 0); p++, len--) {
6103 if (check_domain_name(ptr, p - ptr, dots) != 0)
6110 return(check_domain_name(ptr, p - ptr, dots));
6127#ifdef ACCEPT_LIST_IN_DOMAIN_NAME
6128 return check_domain_name_list(ptr, len, 0);
6130 return check_domain_name(ptr, len, 0);
6135 return check_domain_name(ptr, len, 0);
6138 return check_domain_name_list(ptr, len, 0);
6143 for (; (*ptr != 0) && (len-- > 0); ptr++) {
6144 if(!(isalnum((
unsigned char)*ptr) ||
6145 *ptr ==
'#' || *ptr ==
'%' ||
6146 *ptr ==
'+' || *ptr ==
'-' ||
6147 *ptr ==
'_' || *ptr ==
':' ||
6148 *ptr ==
'.' || *ptr ==
',' ||
6149 *ptr ==
'@' || *ptr ==
'~' ||
6150 *ptr ==
'\\' || *ptr ==
'/' ||
6151 *ptr ==
'[' || *ptr ==
']' ||
6152 *ptr ==
'=' || *ptr ==
' '))
6167 return check_domain_name_list(ptr, len, 0);
6182 log_fatal (
"no memory for reject list!");
6201 log_info(
"Server added to list of rejected servers.");
6204#if defined(NSUPDATE)
6211 if (client != NULL) {
6220#if defined(DHCPv6) && defined(DHCP4o6)
6239 char start_msg[5] = {
'S',
'T',
'A',
'R',
'T' };
6240 char stop_msg[4] = {
'S',
'T',
'O',
'P' };
6241 char poll_msg[4] = {
'P',
'O',
'L',
'L' };
6245 if (h->type != dhcp4o6_type)
6248 cc = recv(dhcp4o6_fd, buf,
sizeof(buf), 0);
6250 return ISC_R_UNEXPECTED;
6254 (memcmp(buf, poll_msg,
sizeof(poll_msg)) == 0)) {
6256 if (dhcp4o6_state < 0)
6257 cc = send(dhcp4o6_fd, stop_msg,
6258 sizeof(stop_msg), 0);
6260 cc = send(dhcp4o6_fd, start_msg,
6261 sizeof(start_msg), 0);
6263 log_error(
"dhcpv4o6_handler: send(): %m");
6264 return ISC_R_IOERROR;
6268 return ISC_R_UNEXPECTED;
6269 memset(&raw, 0,
sizeof(raw));
6272 "no memory buffer.");
6273 return ISC_R_NOMEMORY;
6279 forw_dhcpv4_query(&raw);
6285 (memcmp(buf, stop_msg,
sizeof(stop_msg)) == 0)) {
6287 if (dhcp4o6_state > 0) {
6291 }
else if ((cc == 5) &&
6292 (memcmp(buf, start_msg,
sizeof(start_msg)) == 0)) {
6294 if (dhcp4o6_state == 0)
6300 return ISC_R_UNEXPECTED;
6301 memset(&raw, 0,
sizeof(raw));
6304 "no memory buffer.");
6305 return ISC_R_NOMEMORY;
6311 recv_dhcpv4_response(&raw);
6328static void dhcp4o6_poll(
void *dummy) {
6329 char msg[4] = {
'P',
'O',
'L',
'L' };
6335 if (dhcp4o6_state < 0)
6340 cc = send(dhcp4o6_fd, msg,
sizeof(msg), 0);
6345 tv.tv_usec = random() % 1000000;
6357static void dhcp4o6_resume() {
6362 for (client =
ip->client; client != NULL;
6363 client = client->
next) {
6386 char msg[5] = {
'S',
'T',
'A',
'R',
'T' };
6389 memset(&addrs, 0,
sizeof(addrs));
6391 for (client =
ip->client; client != NULL;
6392 client = client->
next) {
6405 lease->options, NULL,
6408 if ((addrs.len % 16) != 0) {
6421 if (dhcp4o6_state == 1)
6423 log_info(
"dhcp4o6_start: go to UP");
6426 cc = send(dhcp4o6_fd, msg,
sizeof(msg), 0);
6428 log_info(
"dhcp4o6_start: send(): %m");
6438static void dhcp4o6_stop() {
6439 char msg[4] = {
'S',
'T',
'O',
'P' };
6442 if (dhcp4o6_state == -1)
6445 log_info(
"dhcp4o6_stop: go to DOWN");
6448 cc = send(dhcp4o6_fd, msg,
sizeof(msg), 0);
struct option * default_requested_options[NUM_DEFAULT_REQUESTED_OPTS+2+1]
void read_client_leases()
isc_result_t read_client_conf()
void parse_client_statement(struct parse *cfile, struct interface_info *ip, struct client_config *config)
struct client_config top_level_config
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
void data_string_forget(struct data_string *data, const char *file, int line)
int option_state_reference(struct option_state **ptr, struct option_state *bp, const char *file, int line)
int option_state_allocate(struct option_state **ptr, const char *file, int line)
int option_state_dereference(struct option_state **ptr, const char *file, int line)
int packet_dereference(struct packet **ptr, const char *file, int line)
void free_client_lease(struct client_lease *lease, const char *file, int line)
struct client_lease * new_client_lease(char *file, int line) const
int packet_allocate(struct packet **ptr, const char *file, int line)
int buffer_dereference(struct buffer **ptr, const char *file, int line)
enum dhcp_token peek_token(const char **rval, unsigned *rlen, struct parse *cfile)
isc_result_t end_parse(struct parse **cfile)
isc_result_t new_parse(struct parse **cfile, int file, char *inbuf, unsigned buflen, const char *name, int eolp)
void add_timeout(struct timeval *when, void *where, void *what, tvref_t ref, tvunref_t unref)
void cancel_timeout(void *where, void *what)
void save_option(struct universe *universe, struct option_state *options, struct option_cache *oc)
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
const char * pretty_print_option(struct option *option, const unsigned char *data, unsigned len, int emit_commas, int emit_quotes)
int parse_encapsulated_suboptions(struct option_state *options, struct option *eopt, const unsigned char *buffer, unsigned len, struct universe *eu, const char *uname)
int parse_options(struct packet *packet)
void option_space_foreach(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 universe *u, void *stuff, void(*func)(struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *))
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
void do_packet(struct interface_info *interface, struct dhcp_packet *packet, unsigned len, unsigned int from_port, struct iaddr from, struct hardware *hfrom)
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)
int validate_packet(struct packet *packet)
char * format_lease_id(const unsigned char *s, unsigned len, int format, const char *file, int line)
char * quotify_string(const char *s, const char *file, int line)
char * absolute_path(const char *orgpath)
const char * print_time(TIME t)
void dump_raw(unsigned char *buf, unsigned len) const
#define _PATH_DHCLIENT_DB
#define _PATH_DHCLIENT_PID
#define ISC_PATH_RANDOMDEV
void putUShort(unsigned char *, u_int32_t)
u_int32_t getULong(const unsigned char *)
void putULong(unsigned char *, u_int32_t)
void finish_v6only(void *cpp)
int script_go(struct client_state *client)
Calls external script.
int parse_agent_information_option(struct packet *packet, int len, u_int8_t *data)
void bootp(struct packet *packet)
void dhcpv4_client_assignments(void)
int asprintf(char **strp, const char *fmt,...)
isc_result_t read_uuid(u_int8_t *uuid)
void bind_lease(struct client_state *client)
isc_boolean_t no_pid_file
void dhcp(struct packet *packet)
void state_stop(void *cpp)
int dhcp_option_ev_name(char *buf, size_t buflen, struct option *option)
unsigned cons_agent_information_options(struct option_state *cfg_options, struct dhcp_packet *outpacket, unsigned agentix, unsigned length)
void start_v6only(struct client_state *client, uint32_t v6only_wait)
int dhclient_interface_discovery_hook(struct interface_info *tmp)
void dhcpnak(struct packet *packet)
int main(int argc, char **argv)
struct iaddr iaddr_broadcast
struct string_list * client_env
void script_write_params(struct client_state *client, const char *prefix, struct client_lease *lease)
Adds parameters to environment variables for a script.
struct in_addr inaddr_any
void make_discover(struct client_state *client, struct client_lease *lease)
int dhcp_max_agent_option_packet_length
void send_discover(void *cpp)
void make_request(struct client_state *client, struct client_lease *lease)
void initialize_client_option_spaces()
int write_host(struct host_decl *host)
void state_init(void *cpp)
uint32_t check_v6only(struct packet *packet, struct client_state *client)
void make_client_options(struct client_state *client, struct client_lease *lease, u_int8_t *type, struct option_cache *sid, struct iaddr *rip, struct option **prl, struct option_state **op)
struct sockaddr_in sockaddr_broadcast
int bootp_broadcast_always
isc_result_t dhclient_interface_startup_hook(struct interface_info *interface)
void run_stateless(int exit_mode, u_int16_t port)
void client_location_changed()
void discard_duplicate(struct client_lease **lease_list, struct client_lease *lease)
const char * path_dhclient_duid
isc_result_t write_client6_lease(struct client_state *client, struct dhc6_lease *lease, int rewrite, int sync)
int check_collection(struct packet *packet, struct lease *lease, struct collection *collection)
void state_panic(void *cpp)
int write_client_lease(struct client_state *client, struct client_lease *lease, int rewrite, int makesure)
void send_release(void *cpp)
void dhcpack(struct packet *packet)
void state_reboot(void *cpp)
void write_client_pid_file()
void classify(struct packet *packet, struct class *class)
void do_release(struct client_state *client)
const char * path_dhclient_db
void rewrite_client_leases()
void destroy_client_lease(struct client_lease *lease)
const char * path_dhclient_conf
isc_result_t find_class(struct class **c, const char *s, const char *file, int line)
isc_result_t dhcp_set_control_state(control_object_state_t oldstate, control_object_state_t newstate)
void make_release(struct client_state *client, struct client_lease *lease)
void send_decline(void *cpp)
int find_subnet(struct subnet **sp, struct iaddr addr, const char *file, int line)
struct client_lease * packet_to_lease(struct packet *packet, struct client_state *client)
int dhclient_interface_shutdown_hook(struct interface_info *interface)
void unbill_class(struct lease *lease)
void script_write_requested(struct client_state *client)
Write out the environent variable the client requested. Write out the environment variables for the o...
void client_option_envadd(struct option_cache *oc, 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 universe *u, void *stuff)
void write_lease_option(struct option_cache *oc, 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 universe *u, void *stuff)
void send_request(void *cpp)
void db_startup(int testp)
void make_decline(struct client_state *client, struct client_lease *lease)
int write_lease(struct lease *lease)
#define ASSERT_STATE(state_is, state_shouldbe)
void client_envadd(struct client_state *client, const char *prefix, const char *name, const char *fmt,...)
struct data_string default_duid
void state_bound(void *cpp)
isc_result_t form_duid(struct data_string *duid, const char *file, int line)
void dhcpoffer(struct packet *packet)
void state_selecting(void *cpp)
void script_init(struct client_state *client, const char *reason, struct string_list *medium)
Initializes basic variables for a script.
const char * path_dhclient_pid
char * path_dhclient_script
#define D6O_NIS_DOMAIN_NAME
#define D6O_SIP_SERVERS_DNS
#define DHCP4O6_QUERY_UNICAST
#define D6O_NISP_DOMAIN_NAME
#define D6O_DHCP4_O_DHCP6_SERVER
#define D6O_DOMAIN_SEARCH
#define DHCPV6_DHCPV4_QUERY
#define All_DHCP_Relay_Agents_and_Servers
#define DHCPV6_RECONFIGURE
#define DHCPV6_DHCPV4_RESPONSE
#define DHO_VENDOR_ENCAPSULATED_OPTIONS
#define DHO_DHCP_PARAMETER_REQUEST_LIST
#define DHO_NETBIOS_SCOPE
#define DHO_BROADCAST_ADDRESS
#define DHO_DOMAIN_SEARCH
#define FQDN_SERVER_UPDATE
#define DHCP_FIXED_NON_UDP
#define DHO_DHCP_CLIENT_IDENTIFIER
#define FQDN_NO_CLIENT_UPDATE
#define DHO_DHCP_MESSAGE_TYPE
#define DHO_DHCP_RENEWAL_TIME
#define DHO_V6_ONLY_PREFERRED
#define DHO_DHCP_REBINDING_TIME
#define DHO_DHCP_OPTION_OVERLOAD
#define DHO_DHCP_SERVER_IDENTIFIER
#define DHO_DHCP_REQUESTED_ADDRESS
#define DHO_DHCP_LEASE_TIME
#define DHCP_MAX_OPTION_LEN
#define INTERFACE_RUNNING
#define DISCOVER_REQUESTED
void do_packet6(struct interface_info *, const char *, int, int, const struct iaddr *, isc_boolean_t)
void unconfigure6(struct client_state *client, const char *reason)
#define INTERFACE_REQUESTED
void start_info_request6(struct client_state *client)
#define DDNS_INCLUDE_RRSET
struct dhcp_ddns_cb dhcp_ddns_cb_t
void ddns_cancel(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
#define DDNS_STATE_REM_FW_NXRR
#define DDNS_STATE_ADD_FW_YXDHCID
void dhcp_common_objects_setup(void)
void dump_packet(struct packet *)
isc_result_t ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
ssize_t send_packet(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
#define _PATH_DHCLIENT_SCRIPT
void start_release6(struct client_state *client)
#define DDNS_STATE_ADD_FW_NXDOMAIN
void client_dns_remove(struct client_state *client, struct iaddr *addr)
int can_receive_unicast_unconfigured(struct interface_info *)
void dhclient_schedule_updates(struct client_state *client, struct iaddr *addr, int offset)
void dhcpv6_client_assignments(void)
struct universe dhcp_universe
void(* dhcpv6_packet_handler)(struct interface_info *, const char *, int, int, const struct iaddr *, isc_boolean_t)
void start_confirm6(struct client_state *client)
#define DDNS_STATE_REM_FW_YXDHCID
#define INTERFACE_AUTOMATIC
void forget_zone(struct dns_zone **)
#define DISCOVER_UNCONFIGURED
#define _PATH_DHCLIENT_CONF
ssize_t send_packet6(struct interface_info *, const unsigned char *, size_t, struct sockaddr_in6 *)
dhcp_ddns_cb_t * ddns_cb_alloc(const char *file, int line)
void client_dns_update_timeout(void *cp)
int get_dhcid(dhcp_ddns_cb_t *, int, const u_int8_t *, unsigned)
isc_result_t client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb)
void start_init6(struct client_state *client)
void dhcpv6(struct packet *)
void ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
#define print_hex_1(len, data, limit)
struct interface_info * interfaces
struct interface_info * fallback_interface
void discover_interfaces(int state)
int(* dhcp_interface_discovery_hook)(struct interface_info *)
int quiet_interface_discovery
void reinitialize_interfaces()
void(* bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)
int(* dhcp_interface_shutdown_hook)(struct interface_info *)
struct interface_info * dummy_interfaces
isc_result_t(* dhcp_interface_startup_hook)(struct interface_info *)
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)
u_int16_t validate_port(char *port)
const char * piaddr(const struct iaddr addr)
struct iaddr broadcast_addr(struct iaddr subnet, struct iaddr mask)
u_int16_t validate_port_pair(char *port)
int addr_match(struct iaddr *addr, struct iaddrmatch *match)
struct iaddr subnet_number(struct iaddr addr, struct iaddr mask)
char * piaddrmask(struct iaddr *addr, struct iaddr *mask)
isc_result_t dhcp_context_create(int flags, struct in_addr *local4, struct in6_addr *local6)
#define DHCP_DNS_CLIENT_LAZY_INIT
void dhcp_signal_handler(int signal)
#define DHCP_CONTEXT_PRE_DB
#define DHCP_CONTEXT_POST_DB
isc_result_t omapi_generic_new(omapi_object_t **, const char *, int)
isc_result_t omapi_protocol_listen(omapi_object_t *, unsigned, int)
struct __omapi_object omapi_object_t
isc_result_t omapi_init(void)
void * dmalloc(size_t, const char *, int)
void dfree(void *, const char *, int)
int log_error(const char *,...) __attribute__((__format__(__printf__
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int int log_info(const char *,...) __attribute__((__format__(__printf__
#define DHCP_R_INVALIDARG
#define DHCLIENT_DEFAULT_PREFIX_LEN
struct option ** required_options
int bootp_broadcast_always
struct group * on_transmission
struct iaddrmatchlist * reject_list
struct option ** requested_options
struct group * on_receipt
struct string_list * medium
struct client_lease * next
struct option_state * options
struct client_lease * alias
struct dhc6_lease * active_lease
struct client_lease * active
void(* v6_handler)(struct packet *, struct client_state *)
struct dhcp_packet packet
struct client_config * config
struct client_lease * leases
struct dhcp_ddns_cb * ddns_cb
struct interface_info * interface
struct iaddr requested_address
enum dhcp_pending pending
struct client_state * next
struct option_state * sent_options
struct string_list * medium
struct client_lease * new
unsigned char dhcpv6_transaction_id[3]
const unsigned char * data
struct option_state * options
struct option_state * options
struct data_string fwd_name
dns_rdataclass_t dhcid_class
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
struct client_state * client
union executable_statement::@336221350347175166011011356261373334214214051201 data
struct option_cache * option
struct executable_statement * statements
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
struct iaddrmatchlist * next
struct interface_info * next
struct client_state * client
struct hardware hw_address
struct universe * universe
unsigned char dhcpv6_msg_type
struct interface_info * interface
struct option_state * options
unsigned char dhcpv6_transaction_id[3]
struct string_list * next
const int dhcpv6_type_name_max
struct universe fqdn_universe
const char * dhcpv6_type_names[]
int option_dereference(struct option **dest, const char *file, int line)
struct universe dhcpv6_universe
void initialize_common_option_spaces()
struct universe ** universes
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)
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)
struct binding_scope * global_scope
int make_const_option_cache(struct option_cache **oc, struct buffer **buffer, u_int8_t *data, unsigned len, struct option *option, const char *file, int line)