42 #include <dns/result.h> 52 extern int asprintf(
char **strp,
const char *fmt, ...);
83 #define ASSERT_STATE(state_is, state_shouldbe) {} 86 static const char copyright[] =
"Copyright 2004-2017 Internet Systems Consortium.";
87 static const char arr [] =
"All rights reserved.";
88 static const char message [] =
"Internet Systems Consortium DHCP Client";
89 static const char url [] =
"For info, please visit https://www.isc.org/software/dhcp/";
94 #if defined(DHCPv6) && defined(DHCP4o6) 95 int dhcp4o6_state = -1;
122 static isc_result_t write_duid(
struct data_string *duid);
125 static int check_domain_name(
const char *ptr,
size_t len,
int dots);
126 static int check_domain_name_list(
const char *ptr,
size_t len,
int dots);
128 const char *ptr,
size_t len);
149 #if defined(DHCPv6) && defined(DHCP4o6) 150 static void dhcp4o6_poll(
void *dummy);
151 static void dhcp4o6_resume(
void);
152 static void recv_dhcpv4_response(
struct data_string *raw);
153 static int send_dhcpv4_query(
struct client_state *client,
int broadcast);
155 static void dhcp4o6_stop(
void);
156 static void forw_dhcpv4_response(
struct packet *
packet);
157 static void forw_dhcpv4_query(
struct data_string *raw);
164 static const char use_noarg[] =
"No argument for command: %s";
166 static const char use_v6command[] =
"Command not used for DHCPv4: %s";
172 usage(
const char *sfmt,
const char *sarg)
180 #ifdef PRINT_SPECIFIC_CL_ERRORS 188 "[-4|-6] [-SNTPRI1dvrxi] [-nw] -4o6 <port>] [-p <port>]\n" 189 " [-D LL|LLT] [--dad-wait-time seconds]\n" 191 "[-4|-6] [-SNTPRI1dvrxi] [-nw] [-p <port>]\n" 192 " [-D LL|LLT] [--dad-wait-time seconds]\n" 195 "[-I1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n" 197 " [-s server-addr] [-cf config-file]\n" 198 " [-df duid-file] [-lf lease-file]\n" 199 " [-pf pid-file] [--no-pid] [-e VAR=val]\n" 200 " [-sf script-file] [interface]*\n" 201 " [-C <dhcp-client-identifier>] [-B]\n" 202 " [-H <host-name> | -F <fqdn.fqdn>] [--timeout <timeout>]\n" 203 " [-V <vendor-class-identifier>]\n" 204 " [--address-prefix-len length]\n" 205 " [--request-options <request option list>]",
219 int release_mode = 0;
224 int no_dhclient_conf = 0;
225 int no_dhclient_db = 0;
226 int no_dhclient_pid = 0;
227 int no_dhclient_script = 0;
229 int local_family_set = 0;
231 u_int16_t dhcp4o6_port = 0;
242 char *dhcp_client_identifier_arg = NULL;
243 char *dhcp_host_name_arg = NULL;
244 char *dhcp_fqdn_arg = NULL;
245 char *dhcp_vendor_class_identifier_arg = NULL;
246 char *dhclient_request_options = NULL;
249 char *arg_conf = NULL;
250 int arg_conf_len = 0;
251 #ifdef HAVE_LIBCAP_NG 252 int keep_capabilities = 0;
261 fd = open(
"/dev/null", O_RDWR | O_CLOEXEC);
263 fd = open(
"/dev/null", O_RDWR | O_CLOEXEC);
265 fd = open(
"/dev/null", O_RDWR | O_CLOEXEC);
273 #if !(defined(DEBUG) || defined(__CYGWIN32__)) 274 setlogmask(LOG_UPTO(LOG_INFO));
280 if (status != ISC_R_SUCCESS)
281 log_fatal(
"Can't initialize context: %s",
282 isc_result_totext(status));
286 if (status != ISC_R_SUCCESS)
288 isc_result_totext(status));
298 for (i = 1; i < argc; i++) {
299 if (!strcmp(argv[i],
"-r")) {
303 }
else if (!strcmp(argv[i],
"-4")) {
305 log_fatal(
"Client can only do v4 or v6, not " 307 local_family_set = 1;
309 }
else if (!strcmp(argv[i],
"-6")) {
311 log_fatal(
"Client can only do v4 or v6, not " 313 local_family_set = 1;
316 }
else if (!strcmp(argv[i],
"-4o6")) {
318 usage(use_noarg, argv[i-1]);
321 log_debug(
"DHCPv4 over DHCPv6 over ::1 port %d and %d",
323 ntohs(dhcp4o6_port) + 1);
327 }
else if (!strcmp(argv[i],
"-x")) {
331 }
else if (!strcmp(argv[i],
"-p")) {
333 usage(use_noarg, argv[i-1]);
335 log_debug(
"binding to user-specified port %d",
337 }
else if (!strcmp(argv[i],
"-d")) {
340 }
else if (!strcmp(argv[i],
"-pf")) {
342 usage(use_noarg, argv[i-1]);
345 }
else if (!strcmp(argv[i],
"--no-pid")) {
347 }
else if (!strcmp(argv[i],
"-cf")) {
349 usage(use_noarg, argv[i-1]);
351 no_dhclient_conf = 1;
352 }
else if (!strcmp(argv[i],
"-df")) {
354 usage(use_noarg, argv[i-1]);
356 }
else if (!strcmp(argv[i],
"-lf")) {
358 usage(use_noarg, argv[i-1]);
361 }
else if (!strcmp(argv[i],
"-sf")) {
363 usage(use_noarg, argv[i-1]);
365 no_dhclient_script = 1;
366 }
else if (!strcmp(argv[i],
"-1")) {
368 }
else if (!strcmp(argv[i],
"-q")) {
370 }
else if (!strcmp(argv[i],
"-s")) {
372 usage(use_noarg, argv[i-1]);
374 }
else if (!strcmp(argv[i],
"-g")) {
376 usage(use_noarg, argv[i-1]);
378 }
else if (!strcmp(argv[i],
"-nw")) {
380 }
else if (!strcmp(argv[i],
"-n")) {
383 }
else if (!strcmp(argv[i],
"-w")) {
386 }
else if (!strcmp(argv[i],
"-e")) {
389 usage(use_noarg, argv[i-1]);
390 tmp =
dmalloc(strlen(argv[i]) +
sizeof *tmp,
MDL);
393 strcpy(tmp->
string, argv[i]);
397 }
else if (!strcmp(argv[i],
"--address-prefix-len")) {
399 usage(use_noarg, argv[i-1]);
403 if (errno || (*s !=
'\0') ||
405 usage(
"Invalid value for" 406 " --address-prefix-len: %s", argv[i]);
409 }
else if (!strcmp(argv[i],
"-S")) {
411 usage(use_v6command, argv[i]);
413 local_family_set = 1;
417 }
else if (!strcmp(argv[i],
"-N")) {
419 usage(use_v6command, argv[i]);
421 local_family_set = 1;
427 }
else if (!strcmp(argv[i],
"-T")) {
429 usage(use_v6command, argv[i]);
431 local_family_set = 1;
437 }
else if (!strcmp(argv[i],
"-P")) {
439 usage(use_v6command, argv[i]);
441 local_family_set = 1;
447 }
else if (!strcmp(argv[i],
"-R")) {
449 usage(use_v6command, argv[i]);
451 local_family_set = 1;
454 }
else if (!strcmp(argv[i],
"--dad-wait-time")) {
456 usage(use_noarg, argv[i-1]);
460 usage(
"Invalid value for --dad-wait-time: %s", argv[i]);
464 }
else if (!strcmp(argv[i],
"-D")) {
467 usage(use_noarg, argv[i-1]);
468 if (!strcasecmp(argv[i],
"LL")) {
470 }
else if (!strcasecmp(argv[i],
"LLT")) {
473 usage(
"Unknown argument to -D: %s", argv[i]);
475 }
else if (!strcmp(argv[i],
"-i")) {
478 }
else if (!strcmp(argv[i],
"-I")) {
481 }
else if (!strcmp(argv[i],
"-v")) {
483 }
else if (!strcmp(argv[i],
"--version")) {
484 const char vstring[] =
"isc-dhclient-";
492 }
else if (!strcmp(argv[i],
"-C")) {
493 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
494 usage(use_noarg, argv[i-1]);
503 dhcp_client_identifier_arg = argv[i];
504 }
else if (!strcmp(argv[i],
"-B")) {
506 }
else if (!strcmp(argv[i],
"-H")) {
507 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
508 usage(use_noarg, argv[i-1]);
517 if (dhcp_host_name_arg != NULL) {
518 log_error(
"The -H <host-name> and -F <fqdn> arguments are mutually exclusive");
522 dhcp_host_name_arg = argv[i];
523 }
else if (!strcmp(argv[i],
"-F")) {
524 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
525 usage(use_noarg, argv[i-1]);
534 if (dhcp_fqdn_arg != NULL) {
535 log_error(
"Only one -F <fqdn> argument can be specified");
539 if (dhcp_host_name_arg != NULL) {
540 log_error(
"The -F <fqdn> and -H <host-name> arguments are mutually exclusive");
544 dhcp_fqdn_arg = argv[i];
545 }
else if (!strcmp(argv[i],
"--timeout")) {
546 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
547 usage(use_noarg, argv[i-1]);
551 if ((timeout_arg = atoi(argv[i])) <= 0) {
552 log_error(
"timeout option must be > 0 - bad value: %s",argv[i]);
555 }
else if (!strcmp(argv[i],
"-V")) {
556 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
557 usage(use_noarg, argv[i-1]);
566 dhcp_vendor_class_identifier_arg = argv[i];
567 }
else if (!strcmp(argv[i],
"--request-options")) {
568 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
569 usage(use_noarg, argv[i-1]);
573 dhclient_request_options = argv[i];
574 }
else if (!strcmp(argv[i],
"-nc")) {
575 #ifdef HAVE_LIBCAP_NG 576 keep_capabilities = 1;
578 }
else if (argv[i][0] ==
'-') {
579 usage(
"Unknown command: %s", argv[i]);
581 usage(
"No interfaces comamnd -n and " 582 " requested interface %s", argv[i]);
586 status = interface_allocate(&tmp,
MDL);
587 if (status != ISC_R_SUCCESS)
588 log_fatal(
"Can't record interface %s:%s",
589 argv[i], isc_result_totext(status));
590 if (strlen(argv[i]) >=
sizeof(tmp->
name))
591 log_fatal(
"%s: interface name too long (is %ld)",
592 argv[i], (
long)strlen(argv[i]));
593 strcpy(tmp->
name, argv[i]);
595 interface_reference(&tmp->
next,
611 usage(
"PD %s only supports one requested interface",
"-P");
614 #if defined(DHCPv6) && defined(DHCP4o6) 616 (exit_mode || release_mode))
617 log_error(
"Can't relay DHCPv4-over-DHCPv6 " 618 "without a persistent DHCPv6 client");
621 log_fatal(
"DHCPv4-over-DHCPv6 requires an explicit " 622 "interface on which to be applied");
625 if (!no_dhclient_conf && (s = getenv(
"PATH_DHCLIENT_CONF"))) {
628 if (!no_dhclient_db && (s = getenv(
"PATH_DHCLIENT_DB"))) {
631 if (!no_dhclient_pid && (s = getenv(
"PATH_DHCLIENT_PID"))) {
634 if (!no_dhclient_script && (s = getenv(
"PATH_DHCLIENT_SCRIPT"))) {
638 #ifdef HAVE_LIBCAP_NG 640 if (!keep_capabilities) {
641 capng_clear(CAPNG_SELECT_CAPS);
642 capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
644 capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
645 CAP_NET_ADMIN, CAP_NET_RAW,
646 CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1);
647 capng_apply(CAPNG_SELECT_CAPS);
672 log_fatal(
"Failed to get realpath for %s: %s", old_path, strerror(errno));
679 log_fatal(
"Failed to get realpath for %s: %s", old_path, strerror(errno));
688 if ((release_mode || exit_mode) && (
no_pid_file == ISC_FALSE)) {
695 e = fscanf(pidfd,
"%ld\n", &temp);
696 oldpid = (pid_t)temp;
698 if (e != 0 && e != EOF && oldpid) {
699 if (kill(oldpid, SIGTERM) == 0) {
700 log_info(
"Killed old client process");
710 }
else if (errno == ESRCH) {
724 char *new_path_dhclient_pid;
743 int n_len = strlen(
ip->name);
745 new_path_dhclient_pid = (
char*) malloc(pfx + n_len + 6);
747 sprintf(new_path_dhclient_pid + pfx,
"-%s.pid",
ip->name);
749 if ((pidfd = fopen(new_path_dhclient_pid,
"re")) != NULL) {
750 e = fscanf(pidfd,
"%ld\n", &temp);
751 oldpid = (pid_t)temp;
753 if (e != 0 && e != EOF) {
755 if (kill(oldpid, SIGTERM) == 0)
763 free(new_path_dhclient_pid);
772 char procfn[256] =
"";
775 if ((fscanf(pidfp,
"%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
776 snprintf(procfn,256,
"/proc/%u",dhcpid);
777 dhc_running = (access(procfn, F_OK) == 0);
784 log_fatal(
"dhclient(%u) is already running - exiting. ", dhcpid);
809 memcpy(&
giaddr, he->h_addr_list[0],
818 gettimeofday(&
cur_tv, NULL);
825 he = gethostbyname(server);
851 usage(
"Stateless commnad: %s incompatibile with " 852 "other commands",
"-S");
854 #if defined(DHCPv6) && defined(DHCP4o6) 863 if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg !=
'\0')) {
864 arg_conf_len =
asprintf(&arg_conf,
"send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);
866 if ((arg_conf == 0) || (arg_conf_len <= 0))
867 log_fatal(
"Unable to send -C option dhcp-client-identifier");
870 if ((dhcp_host_name_arg != NULL) && (*dhcp_host_name_arg !=
'\0')) {
872 arg_conf_len =
asprintf(&arg_conf,
"send host-name \"%s\";", dhcp_host_name_arg);
874 if ((arg_conf == 0) || (arg_conf_len <= 0))
875 log_fatal(
"Unable to send -H option host-name");
877 char *last_arg_conf = arg_conf;
879 arg_conf_len =
asprintf(&arg_conf,
"%s\nsend host-name \"%s\";", last_arg_conf, dhcp_host_name_arg);
881 if ((arg_conf == 0) || (arg_conf_len <= 0))
882 log_fatal(
"Unable to send -H option host-name");
888 if ((dhcp_fqdn_arg != NULL) && (*dhcp_fqdn_arg !=
'\0')) {
890 arg_conf_len =
asprintf(&arg_conf,
"send fqdn.fqdn \"%s\";", dhcp_fqdn_arg);
892 if ((arg_conf == 0) || (arg_conf_len <= 0))
893 log_fatal(
"Unable to send -F option fqdn.fqdn");
895 char *last_arg_conf = arg_conf;
897 arg_conf_len =
asprintf(&arg_conf,
"%s\nsend fqdn.fqdn \"%s\";", last_arg_conf, dhcp_fqdn_arg);
899 if ((arg_conf == 0) || (arg_conf_len <= 0))
900 log_fatal(
"Unable to send -F option fqdn.fqdn");
908 arg_conf_len =
asprintf(&arg_conf,
"timeout %d;", timeout_arg);
910 if ((arg_conf == 0) || (arg_conf_len <= 0))
911 log_fatal(
"Unable to process --timeout timeout argument");
913 char *last_arg_conf = arg_conf;
915 arg_conf_len =
asprintf(&arg_conf,
"%s\ntimeout %d;", last_arg_conf, timeout_arg);
917 if ((arg_conf == 0) || (arg_conf_len == 0))
918 log_fatal(
"Unable to process --timeout timeout argument");
924 if ((dhcp_vendor_class_identifier_arg != NULL) && (*dhcp_vendor_class_identifier_arg !=
'\0')) {
926 arg_conf_len =
asprintf(&arg_conf,
"send vendor-class-identifier \"%s\";", dhcp_vendor_class_identifier_arg);
928 if ((arg_conf == 0) || (arg_conf_len <= 0))
929 log_fatal(
"Unable to send -V option vendor-class-identifier");
931 char *last_arg_conf = arg_conf;
933 arg_conf_len =
asprintf(&arg_conf,
"%s\nsend vendor-class-identifier \"%s\";", last_arg_conf, dhcp_vendor_class_identifier_arg);
935 if ((arg_conf == 0) || (arg_conf_len <= 0))
936 log_fatal(
"Unable to send -V option vendor-class-identifier");
942 if (dhclient_request_options != NULL) {
944 arg_conf_len =
asprintf(&arg_conf,
"request %s;", dhclient_request_options);
946 if ((arg_conf == 0) || (arg_conf_len <= 0))
947 log_fatal(
"Unable to parse --request-options <request options list> argument");
949 char *last_arg_conf = arg_conf;
951 arg_conf_len =
asprintf(&arg_conf,
"%s\nrequest %s;", last_arg_conf, dhclient_request_options);
953 if ((arg_conf == 0) || (arg_conf_len <= 0))
954 log_fatal(
"Unable to parse --request-options <request options list> argument");
961 if (arg_conf_len == 0)
962 if ((arg_conf_len = strlen(arg_conf)) == 0)
964 log_fatal(
"Unable to process -C/-H/-F/--timeout/-V/--request-options configuration arguments");
969 const char *val = NULL;
972 status =
new_parse(&cfile, -1, arg_conf, arg_conf_len,
"extra dhclient -C/-H/-F/--timeout/-V/--request-options configuration arguments", 0);
975 log_fatal(
"Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
987 log_fatal(
"Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
995 if (
ip->client->config->timeout == 60)
996 ip->client->config->timeout = timeout_arg;
1044 log_info(
"No broadcast interfaces found - exiting.");
1047 }
else if (!release_mode && !exit_mode) {
1064 if (
ip->client->alias != NULL)
1081 unsigned backup_seed = 0;
1084 if (
ip -> hw_address.hlen <=
sizeof seed )
1087 &
ip -> hw_address.hbuf [
ip -> hw_address.hlen -
1088 sizeof seed],
sizeof seed);
1110 if (
ip -> hw_address.hlen <=
sizeof seed )
1113 &
ip->hw_address.hbuf[
ip->hw_address.hlen -
1114 sizeof seed],
sizeof seed);
1118 if ( seed_flag == 0 ) {
1119 if ( backup_seed != 0 ) {
1121 log_info (
"xid: rand init seed (0x%x) built using all" 1122 " available interfaces",seed);
1125 seed =
cur_time^((unsigned) gethostid()) ;
1126 log_info (
"xid: warning: no netdev with useable HWADDR found" 1127 " for seed's uniqueness enforcement");
1128 log_info (
"xid: rand init seed (0x%x) built using gethostid",
1133 srandom(seed + ((
unsigned)(
cur_tv.tv_usec * 1000000)) + (
unsigned)getpid());
1136 srandom(seed + ((
unsigned)(
cur_tv.tv_usec * 1000000)) + (
unsigned)getpid());
1142 setup_ib_interface(
ip);
1161 #if defined(DHCPv6) && defined(DHCP4o6) 1163 dhcp4o6_setup(dhcp4o6_port);
1170 for (client =
ip->client ; client != NULL ;
1171 client = client->
next) {
1175 }
else if (exit_mode) {
1195 for (client =
ip->client ; client ;
1196 client = client->
next) {
1213 tv.tv_usec = random()
1248 if (result != ISC_R_SUCCESS)
1249 log_fatal(
"Can't allocate new generic object: %s\n",
1250 isc_result_totext(result));
1255 if (result != ISC_R_SUCCESS)
1256 log_fatal(
"Can't start OMAPI protocol: %s",
1257 isc_result_totext (result));
1266 #if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \ 1267 defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT) 1268 dmalloc_cutoff_generation = dmalloc_generation;
1269 dmalloc_longterm = dmalloc_outstanding;
1270 dmalloc_outstanding = 0;
1273 #if defined(ENABLE_GENTLE_SHUTDOWN) 1310 isc_result_t result;
1319 usage(
"No interfaces available for stateless command: %s",
"-S");
1362 dhcp4o6_setup(port);
1382 if (result != ISC_R_SUCCESS)
1383 log_fatal(
"Can't allocate new generic object: %s\n",
1384 isc_result_totext(result));
1389 if (result != ISC_R_SUCCESS)
1390 log_fatal(
"Can't start OMAPI protocol: %s",
1391 isc_result_totext(result));
1397 #if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \ 1398 defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT) 1399 dmalloc_cutoff_generation = dmalloc_generation;
1400 dmalloc_longterm = dmalloc_outstanding;
1401 dmalloc_outstanding = 0;
1423 const char *s,
const char *
file,
int line)
1458 ip->client->config->bootp_broadcast_always = 1;
1464 for (g =
ip->client->config->on_transmission; g != NULL; g = g->
next) {
1467 "dhcp-client-identifier") == 0)) {
1510 #if defined(DHCPv6) && defined(DHCP4o6) 1512 if (dhcp4o6_state < 0)
1523 client ->
active -> is_bootp ||
1537 client ->
xid = random ();
1570 client -> xid = client ->
packet.xid;
1573 client -> first_sending =
cur_time;
1574 client -> interval = client -> config -> initial_interval;
1617 for (lp = client -> offered_leases; lp; lp =
next) {
1626 picked ->
next = NULL;
1631 client -> offered_leases = NULL;
1638 client -> state =
S_INIT;
1645 client ->
new = picked;
1663 client -> first_sending =
cur_time;
1664 client -> interval = client -> config -> initial_interval;
1668 client -> xid = client ->
packet.xid;
1691 for (client =
ip -> client; client; client = client -> next) {
1692 if (client -> xid ==
packet -> raw -> xid)
1696 (
packet -> interface -> hw_address.hlen - 1 !=
1697 packet -> raw -> hlen) ||
1698 (memcmp (&
packet -> interface -> hw_address.hbuf [1],
1701 log_debug (
"DHCPACK in wrong transaction.");
1720 log_info (
"packet_to_lease failed.");
1724 client ->
new =
lease;
1732 memset (&ds, 0,
sizeof ds);
1735 packet -> options, client ->
new -> options,
1740 client ->
new -> expiry = 0;
1743 client ->
new -> expiry = 0;
1748 log_error (
"no expiry time on offered lease.");
1754 tv.tv_sec =
cur_tv.tv_sec;
1755 tv.tv_usec =
cur_tv.tv_usec + 500000;
1757 if (tv.tv_usec >= 1000000) {
1759 tv.tv_usec -= 1000000;
1778 packet -> options, client ->
new -> options,
1783 client ->
new -> renewal = 0;
1786 client ->
new -> renewal = 0;
1794 if (!client ->
new -> renewal ||
1795 client ->
new -> renewal > client ->
new -> expiry)
1796 client ->
new -> renewal = client ->
new -> expiry / 2 + 1;
1798 if (client ->
new -> renewal <= 0)
1799 client ->
new -> renewal =
TIME_MAX;
1804 (((random() % client->
new->
renewal) + 3) / 4);
1811 packet -> options, client ->
new -> options,
1816 client ->
new -> rebind = 0;
1819 client ->
new -> rebind = 0;
1822 if (client ->
new -> rebind <= 0 ||
1823 client ->
new -> rebind > client ->
new -> expiry) {
1824 if (client ->
new -> expiry <=
TIME_MAX / 7)
1825 client ->
new -> rebind =
1826 client ->
new -> expiry * 7 / 8;
1828 client ->
new -> rebind =
1829 client ->
new -> expiry / 8 * 7;
1834 if (client ->
new -> renewal > client ->
new -> rebind) {
1835 if (client ->
new -> rebind <=
TIME_MAX / 3)
1836 client ->
new -> renewal =
1837 client ->
new -> rebind * 3 / 4;
1839 client ->
new -> renewal =
1840 client ->
new -> rebind / 4 * 3;
1843 client ->
new -> expiry +=
cur_time;
1845 if (client ->
new -> expiry <
cur_time)
1846 client ->
new -> expiry =
TIME_MAX;
1847 client ->
new -> renewal +=
cur_time;
1848 if (client ->
new -> renewal <
cur_time)
1849 client ->
new -> renewal =
TIME_MAX;
1850 client ->
new -> rebind +=
cur_time;
1851 if (client ->
new -> rebind <
cur_time)
1852 client ->
new -> rebind =
TIME_MAX;
1888 log_info(
"Unable to obtain a lease on first " 1889 "try (declined). Exiting.");
1892 #if defined (CALL_SCRIPT_ON_ONETRY_FAIL) 1919 random() % 1000000 :
cur_tv.tv_usec;
1922 log_info(
"bound to %s -- renewal in %ld seconds.",
1928 #if defined (NSUPDATE) 1950 client -> xid = client ->
packet.xid;
1952 memset (&ds, 0,
sizeof ds);
1958 client -> active -> options,
1961 memcpy (client -> destination.iabuf, ds.
data, 4);
1962 client -> destination.len = 4;
1970 client -> first_sending =
cur_time;
1971 client -> interval = client -> config -> initial_interval;
2039 for (ap =
packet -> interface -> client -> config -> reject_list;
2040 ap; ap = ap ->
next) {
2049 log_info(
"BOOTREPLY from %s rejected by rule %s " 2064 void (*handler) (
struct packet *);
2092 ap; ap = ap -> next) {
2101 log_info(
"%s from %s rejected by rule %s mask %s.",
2115 char addrbuf[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")];
2123 ap ; ap = ap->
next) {
2126 log_info(
"%s from %s rejected by rule %s",
2139 log_info(
"RCV: %s message on %s from %s.",
2143 forw_dhcpv4_response(
packet);
2153 log_info(
"RCV: %s message on %s from %s.",
2164 client = client->
next) {
2173 log_info(
"Packet received, but nothing done with it.");
2189 static void forw_dhcpv4_response(
struct packet *
packet)
2199 if (dhcp4o6_state == -1) {
2200 log_info(
"forw_dhcpv4_response: not ready.");
2205 log_error(
"forw_dhcpv4_response: bad address");
2214 log_info(
"DHCPv4-response from %s missing " 2215 "DHCPv4 Message option.",
2220 memset(&enc_opt_data, 0,
sizeof(enc_opt_data));
2223 log_error(
"forw_dhcpv4_response: error evaluating " 2231 "no memory for encapsulated packet.");
2239 memset(&ds, 0,
sizeof(ds));
2241 log_error(
"forw_dhcpv4_response: no memory buffer.");
2245 ds.data = ds.buffer->data;
2246 ds.len = enc_opt_data.len + 16;
2247 memcpy(ds.buffer->data, enc_opt_data.data, enc_opt_data.len);
2248 memcpy(ds.buffer->data + enc_opt_data.len,
2255 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
2257 log_error(
"forw_dhcpv4_response: send(): %m");
2271 static void recv_dhcpv4_response(
struct data_string *raw)
2277 log_error(
"recv_dhcpv4_response: no interfaces.");
2282 memcpy(from.iabuf, raw->
data + (raw->
len - 16), 16);
2289 log_error(
"recv_dhcpv4_response: no memory for packet.");
2301 log_error(
"recv_dhcpv4_response: no memory for options.");
2322 memset(&dp, 0,
sizeof dp);
2356 const char *
name =
packet -> packet_type ?
"DHCPOFFER" :
"BOOTREPLY";
2365 for (client =
ip -> client; client; client = client -> next)
2366 if (client -> xid ==
packet -> raw -> xid)
2373 (
packet -> interface -> hw_address.hlen - 1 !=
2374 packet -> raw -> hlen) ||
2375 (memcmp (&
packet -> interface -> hw_address.hbuf [1],
2378 log_debug (
"%s in wrong transaction.", name);
2383 sprintf (obuf,
"%s from %s", name,
piaddr (
packet -> client_addr));
2391 for (i = 0 ; req[i] != NULL ; i++) {
2398 option_code_hash_lookup(&
option,
2403 log_info(
"%s: no %s option.", obuf,
2406 log_info(
"%s: no unknown-%u option.",
2418 if (
lease -> address.len ==
sizeof packet -> raw -> yiaddr &&
2419 !memcmp (
lease -> address.iabuf,
2420 &
packet -> raw -> yiaddr,
lease -> address.len)) {
2428 log_info (
"%s: packet_to_lease failed.", obuf);
2434 if (!
packet -> options_valid || !
packet -> packet_type)
2435 lease -> is_bootp = 1;
2438 lease -> medium = client -> medium;
2441 stop_selecting = (client -> first_sending +
2442 client -> config -> select_interval);
2446 if (
lease -> address.len == client -> requested_address.len &&
2447 !memcmp (
lease -> address.iabuf,
2448 client -> requested_address.iabuf,
2449 client -> requested_address.len)) {
2450 lease -> next = client -> offered_leases;
2451 client -> offered_leases =
lease;
2455 if (!client -> offered_leases)
2456 client -> offered_leases =
lease;
2458 for (lp = client -> offered_leases; lp ->
next;
2468 if (stop_selecting <=
cur_tv.tv_sec)
2471 tv.tv_sec = stop_selecting;
2472 tv.tv_usec =
cur_tv.tv_usec;
2495 log_error(
"packet_to_lease: no memory to record lease.\n");
2506 lease->address.len);
2510 lease->next_srv_addr.len);
2512 memset(&data, 0,
sizeof(data));
2514 if (client -> config -> vendor_space_name) {
2520 client -> config -> vendor_space_name &&
2522 (
struct lease *)0, client,
2526 if (!option_code_hash_lookup(&
option,
2530 "option (%s:%d).",
MDL);
2534 client -> config -> vendor_space_name
2560 if (!(i & 2) &&
packet -> raw -> sname [0]) {
2564 if (!
packet -> raw -> sname [len])
2568 log_error (
"dhcpoffer: no memory for server name.\n");
2573 packet -> raw -> sname, len);
2587 log_error (
"dhcpoffer: no memory for filename.\n");
2612 for (client =
ip -> client; client; client = client ->
next)
2620 packet -> raw -> hlen) ||
2624 log_debug (
"DHCPNAK in wrong transaction.");
2643 log_info (
"DHCPNAK with no active lease.\n");
2676 client -> state =
S_INIT;
2695 interval =
cur_time - client -> first_sending;
2699 if (interval > client -> config ->
timeout) {
2707 if (!client -> offered_leases &&
2708 client -> config -> media) {
2711 if (client -> medium) {
2712 client -> medium = client -> medium -> next;
2715 if (!client -> medium) {
2717 log_fatal (
"No valid media types for %s!",
2718 client -> interface -> name);
2720 client -> config -> media;
2724 log_info (
"Trying medium \"%s\" %d",
2725 client -> medium ->
string, increase);
2753 if (
cur_time + client -> interval >
2754 client -> first_sending + client -> config ->
timeout)
2755 client -> interval =
2756 (client -> first_sending +
2760 if (interval < 65536)
2761 client ->
packet.secs = htons (interval);
2763 client ->
packet.secs = htons (65535);
2764 client -> secs = client ->
packet.secs;
2766 #if defined(DHCPv6) && defined(DHCP4o6) 2768 log_info (
"DHCPDISCOVER interval %ld",
2769 (
long)(client -> interval));
2772 log_info (
"DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
2773 client -> name ? client -> name : client -> interface -> name,
2775 ntohs (
sockaddr_broadcast.sin_port), (
long)(client -> interval), ntohl(client -> xid));
2778 #if defined(DHCPv6) && defined(DHCP4o6) 2780 result = send_dhcpv4_query(client, 1);
2787 #if defined(DHCPv6) && defined(DHCP4o6) 2789 log_error(
"%s:%d: Failed to send %d byte long packet.",
2793 log_error(
"%s:%d: Failed to send %d byte long packet over %s " 2805 tv.tv_usec = client->
interval > 1 ? random() % 1000000 :
cur_tv.tv_usec;
2822 loop = lp = client -> active;
2824 log_info (
"No DHCPOFFERS received.");
2828 if (!client -> active && client -> leases)
2832 while (client -> active) {
2833 if (client -> active -> expiry >
cur_time) {
2834 log_info (
"Trying recorded lease %s",
2835 piaddr (client -> active -> address));
2839 client -> active -> medium);
2842 if (client -> alias)
2850 if (cur_time < client -> active -> renewal) {
2852 log_info (
"bound: renewal in %ld %s.",
2853 (
long)(client -> active -> renewal -
2858 random() % 1000000 :
2863 log_info (
"bound: immediate renewal.");
2873 if (!client -> leases) {
2874 client -> leases = client -> active;
2882 for (lp = client -> leases; lp ->
next; lp = lp ->
next)
2884 lp ->
next = client -> active;
2888 client -> active = client -> leases;
2889 client -> leases = client -> leases ->
next;
2894 if (client -> active == loop)
2897 loop = client -> active;
2905 log_info (
"Unable to obtain a lease on first try.%s",
2909 #if defined (CALL_SCRIPT_ON_ONETRY_FAIL) 2917 log_info (
"No working leases in persistent database - sleeping.");
2919 if (client -> alias)
2922 client -> state =
S_INIT;
2925 tv.tv_usec = ((tv.tv_sec -
cur_tv.tv_sec) > 1) ?
2926 random() % 1000000 :
cur_tv.tv_usec;
2938 struct sockaddr_in destination;
2939 struct in_addr from;
2943 interval =
cur_time - client -> first_sending;
2957 interval > client -> config -> reboot_timeout) {
2959 client -> state =
S_INIT;
2968 !client -> medium &&
2969 client -> active -> medium ) {
2970 script_init(client,
"MEDIUM", client -> active -> medium);
2977 client -> medium = client -> active -> medium;
2983 cur_time > client -> active -> expiry) {
2988 if (client -> alias)
2996 if (client -> alias)
3001 client -> state =
S_INIT;
3007 if (!client -> interval)
3008 client -> interval = client -> config -> initial_interval;
3010 client -> interval += ((random () >> 2) %
3011 (2 * client -> interval));
3015 if (client -> interval >
3016 client -> config -> backoff_cutoff)
3017 client -> interval =
3018 ((client -> config -> backoff_cutoff / 2)
3019 + ((random () >> 2) %
3020 client -> config -> backoff_cutoff));
3025 cur_time + client -> interval > client -> active -> expiry)
3026 client -> interval =
3027 client -> active -> expiry -
cur_time + 1;
3033 cur_time > client -> active -> rebind)
3036 memcpy (&destination.sin_addr.s_addr,
3037 client -> destination.iabuf,
3038 sizeof destination.sin_addr.s_addr);
3040 destination.sin_family = AF_INET;
3042 destination.sin_len =
sizeof destination;
3047 memcpy (&from, client -> active -> address.iabuf,
3050 from.s_addr = INADDR_ANY;
3054 client ->
packet.secs = client -> secs;
3056 if (interval < 65536)
3057 client ->
packet.secs = htons (interval);
3059 client ->
packet.secs = htons (65535);
3062 #if defined(DHCPv6) && defined(DHCP4o6) 3067 log_info (
"DHCPREQUEST on %s to %s port %d (xid=0x%x)",
3068 client -> name ? client -> name : client -> interface -> name,
3069 inet_ntoa (destination.sin_addr),
3070 ntohs (destination.sin_port), ntohl(client -> xid));
3072 #if defined(DHCPv6) && defined(DHCP4o6) 3075 if (destination.sin_addr.s_addr == INADDR_BROADCAST)
3077 result = send_dhcpv4_query(client, broadcast);
3079 log_error(
"%s:%d: Failed to send %d byte long packet.",
3084 if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
3086 #if defined(SO_BINDTODEVICE) 3090 log_error(
"%s:%d: Failed to bind fallback interface" 3098 log_error(
"%s:%d: Failed to send %d byte long packet " 3099 "over %s interface.",
MDL,
3103 #if defined(SO_BINDTODEVICE) 3105 SO_BINDTODEVICE, NULL, 0) < 0) {
3106 log_fatal(
"%s:%d: Failed to unbind fallback interface:" 3117 log_error(
"%s:%d: Failed to send %d byte long packet" 3118 " over %s interface.",
MDL,
3125 tv.tv_usec = ((tv.tv_sec -
cur_tv.tv_sec) > 1) ?
3126 random() % 1000000 :
cur_tv.tv_usec;
3137 #if defined(DHCPv6) && defined(DHCP4o6) 3142 log_info (
"DHCPDECLINE on %s to %s port %d (xid=0x%x)",
3148 #if defined(DHCPv6) && defined(DHCP4o6) 3150 result = send_dhcpv4_query(client, 1);
3157 #if defined(DHCPv6) && defined(DHCP4o6) 3159 log_error(
"%s:%d: Failed to send %d byte long packet.",
3163 log_error(
"%s:%d: Failed to send %d byte long packet over %s" 3175 struct sockaddr_in destination;
3176 struct in_addr from;
3178 memcpy (&from, client -> active -> address.iabuf,
3180 memcpy (&destination.sin_addr.s_addr,
3181 client -> destination.iabuf,
3182 sizeof destination.sin_addr.s_addr);
3184 destination.sin_family = AF_INET;
3186 destination.sin_len =
sizeof destination;
3191 client -> active -> expiry =
3192 client -> active -> renewal =
3193 client -> active -> rebind =
cur_time;
3195 log_error (
"Can't release lease: lease write failed.");
3199 #if defined(DHCPv6) && defined(DHCP4o6) 3204 log_info (
"DHCPRELEASE on %s to %s port %d (xid=0x%x)",
3205 client -> name ? client -> name : client -> interface -> name,
3206 inet_ntoa (destination.sin_addr),
3207 ntohs (destination.sin_port), ntohl(client -> xid));
3209 #if defined(DHCPv6) && defined(DHCP4o6) 3212 if (destination.sin_addr.s_addr == INADDR_BROADCAST)
3214 result = send_dhcpv4_query(client, broadcast);
3216 log_error(
"%s:%d: Failed to send %d byte long packet.",
3222 #if defined(SO_BINDTODEVICE) 3226 log_error(
"%s:%d: Failed to bind fallback interface" 3234 log_error(
"%s:%d: Failed to send %d byte long packet" 3235 " over %s interface.",
MDL,
3239 #if defined(SO_BINDTODEVICE) 3241 SO_BINDTODEVICE, NULL, 0) < 0) {
3242 log_fatal(
"%s:%d: Failed to unbind fallback interface:" 3252 log_error (
"%s:%d: Failed to send %d byte long packet" 3253 " over %s interface.",
MDL,
3261 #if defined(DHCPv6) && defined(DHCP4o6) 3273 static int send_dhcpv4_query(
struct client_state *client,
int broadcast) {
3278 if (dhcp4o6_state <= 0) {
3279 log_info(
"send_dhcpv4_query: not ready.");
3289 memset(&ds, 0,
sizeof(ds));
3291 log_error(
"Unable to allocate memory for DHCPv4-query.");
3294 ds.data = ds.buffer->data;
3319 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
3321 log_error(
"send_dhcpv4_query: send(): %m");
3334 static void forw_dhcpv4_query(
struct data_string *raw) {
3340 struct sockaddr_in6 sin6;
3341 int i, send_ret, attempt, success;
3343 attempt = success = 0;
3344 memset(&sin6, 0,
sizeof(sin6));
3345 sin6.sin6_family = AF_INET6;
3348 sin6.sin6_len =
sizeof(sin6);
3350 memset(&addrs, 0,
sizeof(addrs));
3352 for (client =
ip->client; client != NULL;
3353 client = client->
next) {
3366 lease->options, NULL,
3368 ((addrs.len %
sizeof(sin6.sin6_addr)) != 0)) {
3372 if (addrs.len == 0) {
3380 if (send_ret == raw->
len)
3384 for (i = 0; i < addrs.len;
3385 i +=
sizeof(sin6.sin6_addr)) {
3386 memcpy(&sin6.sin6_addr, addrs.data + i,
3387 sizeof(sin6.sin6_addr));
3391 if (send_ret == raw->
len)
3398 log_info(
"forw_dhcpv4_query: sent(%d): %d/%d",
3399 raw->
len, success, attempt);
3415 struct buffer *bp = NULL;
3438 log_error (
"can't make requested address cache.");
3464 for (i = 0 ; prl[i] != NULL ; i++)
3469 log_error(
"can't make parameter list buffer.");
3474 for (i = 0 ; prl[i] != NULL ; i++)
3478 if (!(option_code_hash_lookup(&
option,
3503 memset(&client_identifier, 0,
sizeof(client_identifier));
3506 client_identifier.
len,
MDL))
3507 log_fatal(
"no memory for default DUID!");
3525 memcpy(&client_identifier.
buffer->
data + 5 - hw_len,
3530 memcpy(&client_identifier.
buffer->
data+(1+4),
3537 (u_int8_t *)client_identifier.
data,
3538 client_identifier.
len,
3540 log_error (
"can't make requested client id cache..");
3564 memset (&client ->
packet, 0,
sizeof (client ->
packet));
3569 client -> config -> requested_options,
3573 client -> packet_length =
3575 (
struct lease *)0, client,
3584 client -> config -> vendor_space_name);
3591 client ->
packet.htype = client ->
interface -> hw_address.hbuf [0];
3593 client ->
packet.hlen = client ->
interface -> hw_address.hlen - 1;
3594 client ->
packet.hops = 0;
3595 client ->
packet.xid = random ();
3596 client ->
packet.secs = 0;
3600 client ->
packet.flags = 0;
3604 memset (&(client ->
packet.ciaddr),
3605 0,
sizeof client ->
packet.ciaddr);
3606 memset (&(client ->
packet.yiaddr),
3607 0,
sizeof client ->
packet.yiaddr);
3608 memset (&(client ->
packet.siaddr),
3609 0,
sizeof client ->
packet.siaddr);
3611 if (client -> interface -> hw_address.hlen > 0)
3612 memcpy (client ->
packet.chaddr,
3613 &client -> interface -> hw_address.hbuf [1],
3614 (
unsigned)(client -> interface -> hw_address.hlen - 1));
3617 dump_raw ((
unsigned char *)&client ->
packet, client -> packet_length);
3629 memset (&client ->
packet, 0,
sizeof (client ->
packet));
3637 if (client -> sent_options)
3644 : (
struct iaddr *)0),
3645 client -> config -> requested_options,
3646 &client -> sent_options);
3649 client -> packet_length =
3651 (
struct lease *)0, client,
3654 client -> sent_options,
3660 client -> config -> vendor_space_name);
3666 client ->
packet.htype = client ->
interface -> hw_address.hbuf [0];
3668 client ->
packet.hlen = client ->
interface -> hw_address.hlen - 1;
3669 client ->
packet.hops = 0;
3670 client ->
packet.xid = client -> xid;
3671 client ->
packet.secs = 0;
3675 if (client -> state ==
S_BOUND ||
3678 memcpy (&client ->
packet.ciaddr,
3679 lease -> address.iabuf,
lease -> address.len);
3680 client ->
packet.flags = 0;
3682 memset (&client ->
packet.ciaddr, 0,
3683 sizeof client ->
packet.ciaddr);
3685 client ->config->bootp_broadcast_always)) &&
3687 client ->
packet.flags = 0;
3692 memset (&client ->
packet.yiaddr, 0,
3693 sizeof client ->
packet.yiaddr);
3694 memset (&client ->
packet.siaddr, 0,
3695 sizeof client ->
packet.siaddr);
3696 if (client -> state !=
S_BOUND &&
3700 memset (&client ->
packet.giaddr, 0,
3701 sizeof client ->
packet.giaddr);
3702 if (client -> interface -> hw_address.hlen > 0)
3703 memcpy (client ->
packet.chaddr,
3704 &client -> interface -> hw_address.hbuf [1],
3705 (
unsigned)(client -> interface -> hw_address.hlen - 1));
3708 dump_raw ((
unsigned char *)&client ->
packet, client -> packet_length);
3728 memset (&client ->
packet, 0,
sizeof (client ->
packet));
3729 client -> packet_length =
3731 (
struct lease *)0, client, 0,
3734 client -> config -> vendor_space_name);
3743 client ->
packet.htype = client ->
interface -> hw_address.hbuf [0];
3745 client ->
packet.hlen = client ->
interface -> hw_address.hlen - 1;
3746 client ->
packet.hops = 0;
3747 client ->
packet.xid = client -> xid;
3748 client ->
packet.secs = 0;
3751 client ->
packet.flags = 0;
3756 memset (&client ->
packet.ciaddr, 0,
3757 sizeof client ->
packet.ciaddr);
3758 memset (&client ->
packet.yiaddr, 0,
3759 sizeof client ->
packet.yiaddr);
3760 memset (&client ->
packet.siaddr, 0,
3761 sizeof client ->
packet.siaddr);
3763 memcpy (client ->
packet.chaddr,
3764 &client -> interface -> hw_address.hbuf [1],
3765 client -> interface -> hw_address.hlen);
3768 dump_raw ((
unsigned char *)&client ->
packet, client -> packet_length);
3781 memset (&client ->
packet, 0,
sizeof (client ->
packet));
3788 client -> packet_length =
3790 (
struct lease *)0, client,
3799 client -> config -> vendor_space_name);
3806 client ->
packet.htype = client ->
interface -> hw_address.hbuf [0];
3808 client ->
packet.hlen = client ->
interface -> hw_address.hlen - 1;
3809 client ->
packet.hops = 0;
3810 client ->
packet.xid = random ();
3811 client ->
packet.secs = 0;
3812 client ->
packet.flags = 0;
3813 memcpy (&client ->
packet.ciaddr,
3814 lease -> address.iabuf,
lease -> address.len);
3815 memset (&client ->
packet.yiaddr, 0,
3816 sizeof client ->
packet.yiaddr);
3817 memset (&client ->
packet.siaddr, 0,
3818 sizeof client ->
packet.siaddr);
3820 memcpy (client ->
packet.chaddr,
3821 &client -> interface -> hw_address.hbuf [1],
3822 client -> interface -> hw_address.hlen);
3825 dump_raw ((
unsigned char *)&client ->
packet, client -> packet_length);
3864 for (client =
ip -> client; client; client = client ->
next) {
3865 for (lp = client -> leases; lp; lp = lp ->
next) {
3868 if (client -> active)
3870 client -> active, 1, 0);
3885 for (client =
ip -> client; client; client = client ->
next) {
3886 for (lp = client -> leases; lp; lp = lp ->
next) {
3889 if (client -> active)
3891 client -> active, 1, 0);
3913 const char *name, *dot;
3915 char *preamble = stuff;
3917 memset (&ds, 0,
sizeof ds);
3927 in_options, cfg_options, scope, oc,
MDL)) {
3929 fprintf(
leaseFile,
"%soption %s%s%s", preamble,
3950 const char *preamble)
3963 if (c >=
'0' && c <=
'9')
3966 if (c >=
'a' && c <=
'f')
3967 return c -
'a' + 10;
3969 if (c >=
'A' && c <=
'F')
3970 return c -
'A' + 10;
3977 const char *id_fname =
"/etc/machine-id";
3980 FILE *
file = fopen( id_fname ,
"r");
3983 return ISC_R_IOERROR;
3985 nread = fread(
id, 1,
sizeof id,
file);
3989 log_debug(
"Not enough data in %s", id_fname);
3990 return ISC_R_IOERROR;
3993 for (j = 0; j < 16; j++) {
3999 if (a < 0 || b < 0) {
4000 log_debug(
"Wrong data in %s", id_fname);
4001 return ISC_R_IOERROR;
4003 uuid[j] = a << 4 | b;
4007 uuid[6] = (uuid[6] & 0x0F) | 0x40;
4009 uuid[8] = (uuid[8] & 0x3F) | 0x80;
4011 return ISC_R_SUCCESS;
4044 log_debug(
"Cannot form default DUID from interface %s.",
ip->name);
4048 return ISC_R_UNEXPECTED;
4051 if ((
ip->hw_address.hlen == 0) ||
4052 (
ip->hw_address.hlen >
sizeof(
ip->hw_address.hbuf)))
4053 log_fatal(
"Impossible hardware address length at %s:%d.",
MDL);
4063 len = 2 +
sizeof (uuid);
4072 len = 4 + (
ip->hw_address.hlen - 1);
4077 log_fatal(
"no memory for default DUID!");
4083 memcpy(duid->
buffer->
data + 2, uuid,
sizeof(uuid));
4090 memcpy(duid->
buffer->
data + 8,
ip->hw_address.hbuf + 1,
4091 ip->hw_address.hlen - 1);
4095 memcpy(duid->
buffer->
data + 4,
ip->hw_address.hbuf + 1,
4096 ip->hw_address.hlen - 1);
4103 log_info(
"form_duid: Couldn't allocate memory to log duid!");
4109 return ISC_R_SUCCESS;
4119 if ((duid == NULL) || (duid->
len <= 2))
4126 return ISC_R_IOERROR;
4134 return ISC_R_NOMEMORY;
4136 stat = fprintf(
leaseFile,
"default-duid %s;\n", str);
4139 return ISC_R_IOERROR;
4142 return ISC_R_IOERROR;
4144 return ISC_R_SUCCESS;
4150 int rewrite,
int sync)
4161 return ISC_R_SUCCESS;
4164 if (client == NULL ||
lease == NULL)
4171 return ISC_R_IOERROR;
4175 stat = fprintf(
leaseFile,
"lease6 {\n");
4177 return ISC_R_IOERROR;
4179 stat = fprintf(
leaseFile,
" interface \"%s\";\n",
4182 return ISC_R_IOERROR;
4184 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
4205 (
const unsigned char *) &ia->
iaid, 4,
4210 return ISC_R_IOERROR;
4221 stat = fprintf(
leaseFile,
" %s %s {\n", ianame,
4227 return ISC_R_IOERROR;
4230 stat = fprintf(
leaseFile,
" starts %d;\n" 4235 stat = fprintf(
leaseFile,
" starts %d;\n",
4238 return ISC_R_IOERROR;
4240 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4247 " iaprefix %s/%d {\n",
4251 return ISC_R_IOERROR;
4253 stat = fprintf(
leaseFile,
" starts %d;\n" 4254 " preferred-life %u;\n" 4259 return ISC_R_IOERROR;
4262 write_options(client, addr->
options,
" ");
4266 return ISC_R_IOERROR;
4270 write_options(client, ia->
options,
" ");
4274 return ISC_R_IOERROR;
4277 if (
lease->released) {
4278 stat = fprintf(
leaseFile,
" released;\n");
4280 return ISC_R_IOERROR;
4283 if (
lease->options != NULL)
4284 write_options(client,
lease->options,
" ");
4288 return ISC_R_IOERROR;
4291 return ISC_R_IOERROR;
4295 log_error(
"write_client_lease: fsync(): %m");
4296 return ISC_R_IOERROR;
4300 return ISC_R_SUCCESS;
4323 if (
lease -> is_static)
4336 if (
lease -> is_bootp) {
4343 fprintf (
leaseFile,
" interface \"%s\";\n",
4344 client -> interface -> name);
4349 if (client -> name) {
4350 fprintf (
leaseFile,
" name \"%s\";\n", client -> name);
4356 fprintf (
leaseFile,
" fixed-address %s;\n",
4362 if (
lease -> filename) {
4365 fprintf (
leaseFile,
" filename \"%s\";\n", s);
4375 if (
lease->server_name != NULL) {
4378 fprintf(
leaseFile,
" server-name \"%s\";\n", s);
4387 if (
lease -> medium) {
4390 fprintf (
leaseFile,
" medium \"%s\";\n", s);
4404 memset (&ds, 0,
sizeof ds);
4406 write_options(client,
lease->options,
" ");
4410 fprintf(
leaseFile,
" renew %s\n", tval) < 0)
4415 fprintf(
leaseFile,
" rebind %s\n", tval) < 0)
4420 fprintf(
leaseFile,
" expire %s\n", tval) < 0)
4431 if (!errors && makesure) {
4433 log_info (
"write_client_lease: %m");
4438 return errors ? 0 : 1;
4465 for (sl = client -> env; sl; sl =
next) {
4472 if (client -> interface) {
4474 client -> interface -> name);
4478 "",
"client",
"%s", client -> name);
4481 "",
"medium",
"%s", medium ->
string);
4484 client_envadd (client,
"",
"pid",
"%ld", (
long int)getpid ());
4503 in_options, cfg_options, scope, oc,
MDL)) {
4513 length = strlen(value);
4517 value, length) == 0) {
4522 "option - discarded",
4566 if (
lease->next_srv_addr.len != 0) {
4578 memset (&data, 0,
sizeof data);
4609 (&data, (
struct packet *)0,
4610 (
struct lease *)0, client,
4615 if (broadcast.
len) {
4617 prefix,
"broadcast_address",
4618 "%s",
piaddr (broadcast));
4626 if (
lease->filename) {
4629 strlen(
lease->filename)) == 0) {
4631 "%s",
lease->filename);
4634 "option - discarded",
4639 if (
lease->server_name) {
4642 strlen(
lease->server_name)) == 0 ) {
4644 "%s",
lease->server_name);
4647 "option - discarded",
4648 lease->server_name);
4661 (
unsigned long)(
lease -> expiry));
4683 for (i = 0 ; req[i] != NULL ; i++) {
4708 char reason [] =
"REASON=NBI";
4709 static char client_path [] = CLIENT_PATH;
4712 int pid, wpid, wstatus;
4715 scriptName = client -> config -> script_name;
4719 envp =
dmalloc (((client ? client -> envc : 2) +
4722 log_error (
"No memory for client script environment.");
4729 envp [i++] = sp ->
string;
4733 for (sp = client -> env; sp; sp = sp ->
next) {
4734 envp [i++] = sp ->
string;
4737 envp [i++] = reason;
4740 envp [i++] = client_path;
4741 envp [i] = (
char *)0;
4744 argv [1] = (
char *)0;
4752 wpid = wait (&wstatus);
4753 }
while (wpid != pid && wpid > 0);
4770 for (sp = client -> env; sp; sp =
next) {
4778 gettimeofday(&
cur_tv, NULL);
4779 return (WIFEXITED (wstatus) ?
4780 WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
4784 const char *prefix,
const char *name,
const char *fmt, ...)
4792 va_start (list, fmt);
4793 len = vsnprintf (spbuf,
sizeof spbuf, fmt, list);
4796 val =
dmalloc (strlen (prefix) + strlen (name) + 1 +
4797 len +
sizeof *val,
MDL);
4799 log_error (
"client_envadd: cannot allocate space for variable");
4808 if (len >=
sizeof spbuf) {
4809 va_start (list, fmt);
4810 vsnprintf (s, len + 1, fmt, list);
4816 val ->
next = client -> env;
4817 client -> env = val;
4840 if (j + 1 == buflen)
4850 if (j + 1 == buflen)
4863 static int state = 0;
4881 if ((pid = fork ()) < 0)
4894 (void) open(
"/dev/null", O_RDWR | O_CLOEXEC);
4895 (void) open(
"/dev/null", O_RDWR | O_CLOEXEC);
4896 (void) open(
"/dev/null", O_RDWR | O_CLOEXEC);
4913 pfdesc = open (
path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
4920 pf = fdopen (pfdesc,
"we");
4925 fprintf (pf,
"%ld\n", (
long)getpid ());
4936 for (client =
ip -> client; client; client = client ->
next) {
4937 switch (client ->
state) {
4970 #if defined(DHCPv6) && defined(DHCP4o6) 4972 if (dhcp4o6_state < 0)
4980 client -> xid = random ();
4983 if (client -> active) {
4988 memset (&ds, 0,
sizeof ds);
4990 client -> active -> options,
4994 (
struct lease *)0, client,
4996 client -> active -> options,
4999 memcpy (client -> destination.iabuf,
5001 client -> destination.len = 4;
5008 client -> first_sending =
cur_time;
5009 client -> interval = client -> config -> initial_interval;
5020 if (client -> alias)
5036 #if defined(DHCPv6) && defined(DHCP4o6) 5059 interface_reference (&
ip, last ->
next,
MDL);
5060 interface_dereference (&last ->
next,
MDL);
5062 interface_reference (&last ->
next,
5064 interface_dereference (&
ip ->
next,
5069 interface_reference (&
ip,
5075 interface_dereference (&
ip ->
next,
5082 tmp ->
client ->
interface = tmp;
5084 interface_dereference (&
ip,
MDL);
5133 for (client =
ip->client ; client ; client = client->
next) {
5138 return ISC_R_SUCCESS;
5164 static void shutdown_exit (
void *foo)
5172 #if defined (NSUPDATE) 5189 isc_result_t eresult)
5192 isc_result_t result;
5194 if ((eresult == ISC_R_SUCCESS) &&
5200 if (result == ISC_R_SUCCESS) {
5206 dhclient_ddns_cb_free(ddns_cb,
MDL);
5215 isc_result_t result;
5218 if (client->
ddns_cb != NULL) {
5224 if (ddns_cb != NULL) {
5230 ddns_cb->
cur_func = client_dns_remove_action;
5234 if (result != ISC_R_TIMEDOUT) {
5235 dhclient_ddns_cb_free(ddns_cb,
MDL);
5251 return ISC_R_SUCCESS;
5255 log_info(
"Received signal %d, initiating shutdown.",
5264 for (client =
ip -> client; client; client = client -> next) {
5267 return ISC_R_SUCCESS;
5270 return ISC_R_SUCCESS;
5273 if (client -> active &&
5274 client -> active -> expiry >
cur_time) {
5275 #if defined (NSUPDATE) 5297 tv.tv_sec =
cur_tv.tv_sec;
5298 tv.tv_usec =
cur_tv.tv_usec + 1;
5301 return ISC_R_SUCCESS;
5304 #if defined (NSUPDATE) 5315 isc_result_t status = ISC_R_FAILURE;
5317 if ((client != NULL) &&
5318 ((client->
active != NULL) ||
5331 if (status != ISC_R_TIMEDOUT) {
5367 isc_result_t eresult)
5369 isc_result_t result;
5386 ddns_cb->
cur_func = client_dns_update_action;
5389 if (result == ISC_R_SUCCESS) {
5395 case ISC_R_TIMEDOUT:
5403 if (ddns_cb->
zone != NULL) {
5409 ddns_cb->
cur_func = client_dns_update_action;
5415 tv.tv_usec =
cur_tv.tv_usec;
5417 ddns_cb, NULL, NULL);
5421 dhclient_ddns_cb_free(ddns_cb,
MDL);
5439 if (!client -> sent_options)
5440 return ISC_R_SUCCESS;
5444 return ISC_R_SUCCESS;
5450 (
struct lease *)0, client,
5451 client -> sent_options,
5454 return ISC_R_SUCCESS;
5461 (
struct lease *)0, client,
5462 client -> sent_options,
5465 return ISC_R_SUCCESS;
5471 (
struct lease *)0, client,
5472 client -> sent_options,
5475 return ISC_R_SUCCESS;
5487 memset(&client_identifier, 0,
sizeof(client_identifier));
5511 client_identifier.data,
5512 client_identifier.len);
5530 (client_identifier.data[0] == 255)) {
5535 if (client_identifier.len <= 5)
5536 log_fatal(
"Impossible condition at %s:%d.",
5539 client_identifier.data + 5,
5540 client_identifier.len - 5);
5542 result =
get_dhcid(ddns_cb, ddns_v4_type,
5543 client_identifier.data,
5544 client_identifier.len);
5554 return ISC_R_SUCCESS;
5563 rcode = ISC_R_FAILURE;
5569 if (rcode == ISC_R_SUCCESS) {
5570 rcode = ISC_R_TIMEDOUT;
5593 if (client->
ddns_cb != NULL) {
5600 if (ddns_cb != NULL) {
5601 ddns_cb->
lease = (
void *)client;
5614 ddns_cb->
cur_func = client_dns_update_action;
5618 tv.tv_sec =
cur_tv.tv_sec + offset;
5619 tv.tv_usec =
cur_tv.tv_usec;
5621 ddns_cb, NULL, NULL);
5623 log_error(
"Unable to allocate dns update state for %s",
5632 struct servent *ent;
5646 ent = getservbyname(
"dhcpc",
"udp");
5648 ent = getservbyname(
"bootpc",
"udp");
5653 #ifndef __CYGWIN32__ 5677 static int check_domain_name(
const char *ptr,
size_t len,
int dots)
5682 if ((len == 0) || (len > 256))
5687 for (p=ptr; (*p != 0) && (len-- > 0); p++) {
5688 if ((*p ==
'-') || (*p ==
'_')) {
5690 if (((p - ptr) == 0) || (len == 0) || (p[1] ==
'.'))
5692 }
else if (*p ==
'.') {
5696 if ((d <= 0) || (d >= 64))
5699 if ((dots > 0) && (len > 0))
5701 }
else if (isalnum((
unsigned char)*p) == 0) {
5706 return(dots ? -1 : 0);
5709 static int check_domain_name_list(
const char *ptr,
size_t len,
int dots)
5714 if ((ptr == NULL) || (len == 0))
5717 for (p=ptr; (*p != 0) && (len > 0); p++, len--) {
5721 if (check_domain_name(ptr, p - ptr, dots) != 0)
5728 return(check_domain_name(ptr, p - ptr, dots));
5745 #ifdef ACCEPT_LIST_IN_DOMAIN_NAME 5746 return check_domain_name_list(ptr, len, 0);
5748 return check_domain_name(ptr, len, 0);
5753 return check_domain_name(ptr, len, 0);
5756 return check_domain_name_list(ptr, len, 0);
5761 for (; (*ptr != 0) && (len-- > 0); ptr++) {
5762 if(!(isalnum((
unsigned char)*ptr) ||
5763 *ptr ==
'#' || *ptr ==
'%' ||
5764 *ptr ==
'+' || *ptr ==
'-' ||
5765 *ptr ==
'_' || *ptr ==
':' ||
5766 *ptr ==
'.' || *ptr ==
',' ||
5767 *ptr ==
'@' || *ptr ==
'~' ||
5768 *ptr ==
'\\' || *ptr ==
'/' ||
5769 *ptr ==
'[' || *ptr ==
']' ||
5770 *ptr ==
'=' || *ptr ==
' '))
5785 return check_domain_name_list(ptr, len, 0);
5800 log_fatal (
"no memory for reject list!");
5819 log_info(
"Server added to list of rejected servers.");
5828 if (client != NULL) {
5836 #if defined(DHCPv6) && defined(DHCP4o6) 5855 char start_msg[5] = {
'S',
'T',
'A',
'R',
'T' };
5856 char stop_msg[4] = {
'S',
'T',
'O',
'P' };
5857 char poll_msg[4] = {
'P',
'O',
'L',
'L' };
5861 if (h->type != dhcp4o6_type)
5864 cc = recv(dhcp4o6_fd, buf,
sizeof(buf), 0);
5866 return ISC_R_UNEXPECTED;
5870 (memcmp(buf, poll_msg,
sizeof(poll_msg)) == 0)) {
5872 if (dhcp4o6_state < 0)
5873 cc = send(dhcp4o6_fd, stop_msg,
5874 sizeof(stop_msg), 0);
5876 cc = send(dhcp4o6_fd, start_msg,
5877 sizeof(start_msg), 0);
5879 log_error(
"dhcpv4o6_handler: send(): %m");
5880 return ISC_R_IOERROR;
5884 return ISC_R_UNEXPECTED;
5885 memset(&raw, 0,
sizeof(raw));
5888 "no memory buffer.");
5889 return ISC_R_NOMEMORY;
5895 forw_dhcpv4_query(&raw);
5901 (memcmp(buf, stop_msg,
sizeof(stop_msg)) == 0)) {
5903 if (dhcp4o6_state > 0) {
5907 }
else if ((cc == 5) &&
5908 (memcmp(buf, start_msg,
sizeof(start_msg)) == 0)) {
5910 if (dhcp4o6_state == 0)
5916 return ISC_R_UNEXPECTED;
5917 memset(&raw, 0,
sizeof(raw));
5920 "no memory buffer.");
5921 return ISC_R_NOMEMORY;
5927 recv_dhcpv4_response(&raw);
5933 return ISC_R_SUCCESS;
5944 static void dhcp4o6_poll(
void *dummy) {
5945 char msg[4] = {
'P',
'O',
'L',
'L' };
5951 if (dhcp4o6_state < 0)
5956 cc = send(dhcp4o6_fd, msg,
sizeof(msg), 0);
5961 tv.tv_usec = random() % 1000000;
5973 static void dhcp4o6_resume() {
5978 for (client =
ip->client; client != NULL;
5979 client = client->
next) {
6002 char msg[5] = {
'S',
'T',
'A',
'R',
'T' };
6005 memset(&addrs, 0,
sizeof(addrs));
6007 for (client =
ip->client; client != NULL;
6008 client = client->
next) {
6021 lease->options, NULL,
6024 if ((addrs.len % 16) != 0) {
6037 if (dhcp4o6_state == 1)
6039 log_info(
"dhcp4o6_start: go to UP");
6042 cc = send(dhcp4o6_fd, msg,
sizeof(msg), 0);
6044 log_info(
"dhcp4o6_start: send(): %m");
6054 static void dhcp4o6_stop() {
6055 char msg[4] = {
'S',
'T',
'O',
'P' };
6058 if (dhcp4o6_state == -1)
6061 log_info(
"dhcp4o6_stop: go to DOWN");
6064 cc = send(dhcp4o6_fd, msg,
sizeof(msg), 0);
void do_packet6(struct interface_info *, const char *, int, int, const struct iaddr *, isc_boolean_t)
void state_selecting(void *cpp)
#define DHCP_FIXED_NON_UDP
#define _PATH_DHCLIENT_CONF
void(* dhcpv6_packet_handler)(struct interface_info *, const char *, int, int, const struct iaddr *, isc_boolean_t)
void send_discover(void *cpp)
void unbill_class(struct lease *lease)
struct client_lease * alias
int parse_encapsulated_suboptions(struct option_state *options, struct option *eopt, const unsigned char *buffer, unsigned len, struct universe *eu, const char *uname)
isc_result_t omapi_protocol_listen(omapi_object_t *, unsigned, int)
struct binding_scope * global_scope
#define _PATH_DHCLIENT_PID
struct universe * universe
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 group * on_receipt
unsigned char dhcpv6_transaction_id[3]
#define _PATH_DHCLIENT_SCRIPT
void save_option(struct universe *universe, struct option_state *options, struct option_cache *oc)
struct client_lease * new
void do_release(struct client_state *client)
const char * piaddr(const struct iaddr addr)
void rewrite_client_leases()
#define FQDN_NO_CLIENT_UPDATE
#define DHO_DOMAIN_SEARCH
#define DDNS_STATE_ADD_FW_NXDOMAIN
void dhcpoffer(struct packet *packet)
unsigned char dhcpv6_transaction_id[3]
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)
void dhcpnak(struct packet *packet)
int get_dhcid(dhcp_ddns_cb_t *, int, const u_int8_t *, unsigned)
isc_result_t end_parse(struct parse **cfile)
const char * path_dhclient_db
void(* bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)
#define All_DHCP_Relay_Agents_and_Servers
void start_release6(struct client_state *client)
char * piaddrmask(struct iaddr *addr, struct iaddr *mask)
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
void start_info_request6(struct client_state *client)
void send_decline(void *cpp)
void client_dns_update_timeout(void *cp)
void cancel_timeout(void(*)(void *) where, void *what)
#define print_hex_1(len, data, limit)
#define DHO_DHCP_PARAMETER_REQUEST_LIST
int dhcp_max_agent_option_packet_length
struct client_lease * packet_to_lease(struct packet *packet, struct client_state *client)
#define DHCP_R_INVALIDARG
struct group * on_transmission
#define DISCOVER_REQUESTED
int script_go(struct client_state *client)
Calls external script.
struct iaddr requested_address
const char * dhcpv6_type_names[]
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
int write_client_lease(struct client_state *client, struct client_lease *lease, int rewrite, int makesure)
struct client_state * client
int can_receive_unicast_unconfigured(struct interface_info *)
struct iaddr iaddr_broadcast
void reinitialize_interfaces()
#define DHCPV6_RECONFIGURE
struct client_state * next
#define DHCP_CONTEXT_PRE_DB
#define DHO_DHCP_LEASE_TIME
void dhcpack(struct packet *packet)
unsigned cons_agent_information_options(struct option_state *cfg_options, struct dhcp_packet *outpacket, unsigned agentix, unsigned length)
struct universe dhcp_universe
struct option_state * options
dhcp_ddns_cb_t * ddns_cb_alloc(const char *file, int line)
void data_string_forget(struct data_string *data, const char *file, int line)
void bootp(struct packet *packet)
const char * pretty_print_option(struct option *option, const unsigned char *data, unsigned len, int emit_commas, int emit_quotes)
#define INTERFACE_RUNNING
void send_release(void *cpp)
int log_error(const char *,...) __attribute__((__format__(__printf__
struct string_list * client_env
#define DDNS_INCLUDE_RRSET
void client_envadd(struct client_state *client, const char *prefix, const char *name, const char *fmt,...)
void add_timeout(struct timeval *when, void(*)(void *) where, void *what, tvref_t ref, tvunref_t unref)
void dump_packet(struct packet *)
#define DDNS_STATE_REM_FW_YXDHCID
#define DHO_DHCP_REBINDING_TIME
#define DHO_NETBIOS_SCOPE
#define DHCPV6_DHCPV4_QUERY
const char * path_dhclient_duid
enum dhcp_token peek_token(const char **rval, unsigned *rlen, struct parse *cfile)
struct data_string fwd_name
void write_client_pid_file()
void state_panic(void *cpp)
void forget_zone(struct dns_zone **)
struct data_string default_duid
struct option_state * options
void ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
void do_packet(struct interface_info *interface, struct dhcp_packet *packet, unsigned len, unsigned int from_port, struct iaddr from, struct hardware *hfrom)
#define D6O_NIS_DOMAIN_NAME
unsigned char dhcpv6_msg_type
#define DHO_DHCP_SERVER_IDENTIFIER
void log_fatal(const char *,...) __attribute__((__format__(__printf__
void(* v6_handler)(struct packet *, struct client_state *)
#define DHCP_CONTEXT_POST_DB
enum dhcp_pending pending
isc_result_t form_duid(struct data_string *duid, const char *file, int line)
struct executable_statement * statements
void state_init(void *cpp)
#define INTERFACE_AUTOMATIC
int option_state_reference(struct option_state **ptr, struct option_state *bp, const char *file, int line)
const char * print_time(TIME t)
struct option * default_requested_options[]
void read_client_leases()
struct iaddr subnet_number(struct iaddr addr, struct iaddr mask)
u_int16_t validate_port(char *port)
void dhcp_signal_handler(int signal)
int find_subnet(struct subnet **sp, struct iaddr addr, const char *file, int line)
void execute_statements_in_scope(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct group *group, struct group *limiting_group, struct on_star *on_star)
void make_request(struct client_state *client, struct client_lease *lease)
struct interface_info * fallback_interface
isc_result_t dhclient_interface_startup_hook(struct interface_info *interface)
int option_state_allocate(struct option_state **ptr, const char *file, int line)
const char * path_dhclient_pid
struct iaddrmatchlist * next
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)
isc_result_t dhcp_context_create(int flags, struct in_addr *local4, struct in6_addr *local6)
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)
#define DHCPV6_DHCPV4_RESPONSE
int write_host(struct host_decl *host)
struct option_state * options
struct option ** requested_options
void classify(struct packet *packet, struct class *class)
void script_init(struct client_state *client, const char *reason, struct string_list *medium)
Initializes basic variables for a script.
#define DHCP_MAX_OPTION_LEN
int main(int argc, char **argv)
void(* store_length)(unsigned char *, u_int32_t)
dns_rdataclass_t dhcid_class
void make_decline(struct client_state *client, struct client_lease *lease)
#define DHCP_DNS_CLIENT_LAZY_INIT
void bind_lease(struct client_state *client)
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
#define DHO_BROADCAST_ADDRESS
struct option_cache * option
struct interface_info * interface
isc_result_t read_uuid(u_int8_t *uuid)
ssize_t send_packet6(struct interface_info *, const unsigned char *, size_t, struct sockaddr_in6 *)
int write_lease(struct lease *lease)
void putULong(unsigned char *, u_int32_t)
void run_stateless(int exit_mode, u_int16_t port)
void send_request(void *cpp)
isc_result_t omapi_generic_new(omapi_object_t **, const char *, int)
#define D6O_DOMAIN_SEARCH
ssize_t send_packet(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
int cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, struct lease *lease, struct client_state *client_state, int mms, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, int overload_avail, int terminate, int bootpp, struct data_string *prl, const char *vuname)
void start_confirm6(struct client_state *client)
void dfree(void *, const char *, int)
isc_boolean_t no_pid_file
struct client_lease * next
void ddns_cancel(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
struct option_state * sent_options
const char * path_dhclient_conf
struct hardware hw_address
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
int dhclient_interface_discovery_hook(struct interface_info *tmp)
struct client_state * client
struct option_state * options
int asprintf(char **strp, const char *fmt,...)
int int log_info(const char *,...) __attribute__((__format__(__printf__
int bootp_broadcast_always
u_int16_t validate_port_pair(char *port)
void * dmalloc(size_t, const char *, int)
int parse_options(struct packet *packet)
struct interface_info * interfaces
void free_client_lease(struct client_lease *lease, const char *file, int line)
#define _PATH_DHCLIENT_DB
u_int32_t getULong(const unsigned char *)
int validate_packet(struct packet *packet)
struct client_config top_level_config
struct iaddr broadcast_addr(struct iaddr subnet, struct iaddr mask)
struct option ** required_options
union executable_statement::@7 data
void state_reboot(void *cpp)
int check_collection(struct packet *packet, struct lease *lease, struct collection *collection)
void destroy_client_lease(struct client_lease *lease)
void db_startup(int testp)
int parse_agent_information_option(struct packet *packet, int len, u_int8_t *data)
#define ASSERT_STATE(state_is, state_shouldbe)
char * path_dhclient_script
void parse_client_statement(struct parse *cfile, struct interface_info *ip, struct client_config *config)
struct universe ** universes
char * format_lease_id(const unsigned char *s, unsigned len, int format, const char *file, int line)
#define DHCP4O6_QUERY_UNICAST
int quiet_interface_discovery
isc_result_t(* dhcp_interface_startup_hook)(struct interface_info *)
#define DISCOVER_UNCONFIGURED
struct client_lease * active
isc_result_t client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb)
int option_state_dereference(struct option_state **ptr, const char *file, int line)
void start_init6(struct client_state *client)
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 *))
void initialize_common_option_spaces()
void make_discover(struct client_state *client, struct client_lease *lease)
void dhcpv6(struct packet *)
void unconfigure6(struct client_state *client, const char *reason)
void client_dns_remove(struct client_state *client, struct iaddr *addr)
const int dhcpv6_type_name_max
int addr_match(struct iaddr *addr, struct iaddrmatch *match)
struct dhcp_packet packet
void state_bound(void *cpp)
struct interface_info * next
struct universe dhcpv6_universe
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)
#define DHCLIENT_DEFAULT_PREFIX_LEN
int packet_dereference(struct packet **ptr, const char *file, int line)
int packet_allocate(struct packet **ptr, const char *file, int line)
void make_release(struct client_state *client, struct client_lease *lease)
struct string_list * next
isc_result_t read_client_conf()
struct interface_info * dummy_interfaces
isc_result_t find_class(struct class **c, const char *s, const char *file, int line)
void script_write_requested(struct client_state *client)
Write out the environent variable the client requested. Write out the environment variables for the o...
#define FQDN_SERVER_UPDATE
struct client_lease * new_client_lease(char *file, int line) const
#define DDNS_STATE_ADD_FW_YXDHCID
#define D6O_DHCP4_O_DHCP6_SERVER
void dhcpv4_client_assignments(void)
void dump_raw(unsigned char *buf, unsigned len) const
void dhcpv6_client_assignments(void)
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
struct iaddrmatchlist * reject_list
struct string_list * medium
struct client_config * config
#define D6O_SIP_SERVERS_DNS
struct sockaddr_in sockaddr_broadcast
void dhclient_schedule_updates(struct client_state *client, struct iaddr *addr, int offset)
int dhcp_option_ev_name(char *buf, size_t buflen, struct option *option)
int(* dhcp_interface_discovery_hook)(struct interface_info *)
struct in_addr inaddr_any
struct universe fqdn_universe
void dhcp(struct packet *packet)
#define DHO_DHCP_OPTION_OVERLOAD
#define D6O_NISP_DOMAIN_NAME
option_code_hash_t * code_hash
#define DHO_DHCP_RENEWAL_TIME
struct string_list * medium
#define DHO_DHCP_CLIENT_IDENTIFIER
struct dhcp_ddns_cb * ddns_cb
void putUShort(unsigned char *, u_int32_t)
isc_result_t dhcp_set_control_state(control_object_state_t oldstate, control_object_state_t newstate)
char * quotify_string(const char *s, const char *file, int line)
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
const unsigned char * data
struct interface_info * interface
#define DHO_DHCP_MESSAGE_TYPE
void dhcp_common_objects_setup(void)
void(* store_tag)(unsigned char *, u_int32_t)
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)
#define DDNS_STATE_REM_FW_NXRR
int(* dhcp_interface_shutdown_hook)(struct interface_info *)
void discover_interfaces(int state)
isc_result_t new_parse(struct parse **cfile, int file, char *inbuf, unsigned buflen, const char *name, int eolp)
struct dhc6_lease * active_lease
#define INTERFACE_REQUESTED
int dhclient_interface_shutdown_hook(struct interface_info *interface)
void script_write_params(struct client_state *client, const char *prefix, struct client_lease *lease)
Adds parameters to environment variables for a script.
int option_dereference(struct option **dest, const char *file, int line)
#define DHO_VENDOR_ENCAPSULATED_OPTIONS
void client_location_changed()
void state_stop(void *cpp)
isc_result_t omapi_init(void)
#define DHO_DHCP_REQUESTED_ADDRESS
int buffer_dereference(struct buffer **ptr, const char *file, int line)
isc_result_t ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
isc_result_t write_client6_lease(struct client_state *client, struct dhc6_lease *lease, int rewrite, int sync)
int bootp_broadcast_always