36 #include <dns/result.h>
52 extern int asprintf(
char **strp,
const char *fmt, ...);
85 #define ASSERT_STATE(state_is, state_shouldbe) {}
88 static const char copyright[] =
"Copyright 2004-2018 Internet Systems Consortium.";
89 static const char arr [] =
"All rights reserved.";
90 static const char message [] =
"Internet Systems Consortium DHCP Client";
91 static const char url [] =
"For info, please visit https://www.isc.org/software/dhcp/";
96 #if defined(DHCPv6) && defined(DHCP4o6)
97 int dhcp4o6_state = -1;
114 int dad_wait_time = 0;
115 int prefix_len_hint = 0;
129 static isc_result_t write_duid(
struct data_string *duid);
132 static int check_domain_name(
const char *ptr,
size_t len,
int dots);
133 static int check_domain_name_list(
const char *ptr,
size_t len,
int dots);
135 const char *ptr,
size_t len);
156 #if defined(DHCPv6) && defined(DHCP4o6)
157 static void dhcp4o6_poll(
void *dummy);
158 static void dhcp4o6_resume(
void);
159 static void recv_dhcpv4_response(
struct data_string *raw);
160 static int send_dhcpv4_query(
struct client_state *client,
int broadcast);
162 static void dhcp4o6_stop(
void);
163 static void forw_dhcpv4_response(
struct packet *
packet);
164 static void forw_dhcpv4_query(
struct data_string *raw);
171 static const char use_noarg[] =
"No argument for command: %s";
173 static const char use_v6command[] =
"Command not used for DHCPv4: %s";
178 #define DHCLIENT_USAGE0 \
179 "[-4|-6] [-SNTPRI1dvrxi] [-nw] -4o6 <port>] [-p <port>] [-D LL|LLT]\n" \
180 " [--dad-wait-time <seconds>] [--prefix-len-hint <length>]\n" \
181 " [--decline-wait-time <seconds>]\n" \
182 " [--address-prefix-len <length>]\n"
184 #define DHCLIENT_USAGE0 \
185 "[-4|-6] [-SNTPRI1dvrxi] [-nw] [-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"
191 #define DHCLIENT_USAGE0 \
192 "[-I1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n" \
193 " [--decline-wait-time <seconds>]\n"
196 #define DHCLIENT_USAGEC \
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 " [--request-options <request option list>]"
206 #define DHCLIENT_USAGEH "{--version|--help|-h}"
211 usage(
const char *sfmt,
const char *sarg)
219 #ifdef PRINT_SPECIFIC_CL_ERRORS
244 int release_mode = 0;
249 int no_dhclient_conf = 0;
250 int no_dhclient_db = 0;
251 int no_dhclient_pid = 0;
252 int no_dhclient_script = 0;
254 int local_family_set = 0;
256 u_int16_t dhcp4o6_port = 0;
266 char *dhcp_client_identifier_arg = NULL;
267 char *dhcp_host_name_arg = NULL;
268 char *dhcp_fqdn_arg = NULL;
269 char *dhcp_vendor_class_identifier_arg = NULL;
270 char *dhclient_request_options = NULL;
273 char *arg_conf = NULL;
274 int arg_conf_len = 0;
275 #ifdef HAVE_LIBCAP_NG
276 int keep_capabilities = 0;
285 fd = open(
"/dev/null", O_RDWR | O_CLOEXEC);
287 fd = open(
"/dev/null", O_RDWR | O_CLOEXEC);
289 fd = open(
"/dev/null", O_RDWR | O_CLOEXEC);
297 #if !(defined(DEBUG) || defined(__CYGWIN32__))
298 setlogmask(LOG_UPTO(LOG_INFO));
302 for (i = 1; i < argc; i++) {
303 if (!strcmp(argv[i],
"-r")) {
305 }
else if (!strcmp(argv[i],
"-x")) {
307 }
else if (!strcmp(argv[i],
"-d")) {
309 }
else if (!strcmp(argv[i],
"--version")) {
310 const char vstring[] =
"isc-dhclient-";
318 }
else if (!strcmp(argv[i],
"--help") ||
319 !strcmp(argv[i],
"-h")) {
320 const char *pname = isc_file_basename(
progname);
344 if ((pid = fork ()) < 0)
350 (void) close(
dfd[1]);
354 n = read(
dfd[0], &buf, 1);
357 }
while (n == -1 && errno == EINTR);
361 (void) close(
dfd[0]);
368 log_fatal(
"Can't initialize context: %s",
369 isc_result_totext(status));
375 isc_result_totext(status));
385 for (i = 1; i < argc; i++) {
386 if (!strcmp(argv[i],
"-r")) {
390 }
else if (!strcmp(argv[i],
"-4")) {
392 log_fatal(
"Client can only do v4 or v6, not "
394 local_family_set = 1;
396 }
else if (!strcmp(argv[i],
"-6")) {
398 log_fatal(
"Client can only do v4 or v6, not "
400 local_family_set = 1;
403 }
else if (!strcmp(argv[i],
"-4o6")) {
405 usage(use_noarg, argv[i-1]);
408 log_debug(
"DHCPv4 over DHCPv6 over ::1 port %d and %d",
410 ntohs(dhcp4o6_port) + 1);
414 }
else if (!strcmp(argv[i],
"-x")) {
418 }
else if (!strcmp(argv[i],
"-p")) {
420 usage(use_noarg, argv[i-1]);
422 log_debug(
"binding to user-specified port %d",
424 }
else if (!strcmp(argv[i],
"-d")) {
427 }
else if (!strcmp(argv[i],
"-pf")) {
429 usage(use_noarg, argv[i-1]);
432 }
else if (!strcmp(argv[i],
"--no-pid")) {
434 }
else if (!strcmp(argv[i],
"-cf")) {
436 usage(use_noarg, argv[i-1]);
438 no_dhclient_conf = 1;
439 }
else if (!strcmp(argv[i],
"-df")) {
441 usage(use_noarg, argv[i-1]);
443 }
else if (!strcmp(argv[i],
"-lf")) {
445 usage(use_noarg, argv[i-1]);
448 }
else if (!strcmp(argv[i],
"-sf")) {
450 usage(use_noarg, argv[i-1]);
452 no_dhclient_script = 1;
453 }
else if (!strcmp(argv[i],
"-1")) {
455 }
else if (!strcmp(argv[i],
"-q")) {
457 }
else if (!strcmp(argv[i],
"-s")) {
459 usage(use_noarg, argv[i-1]);
461 }
else if (!strcmp(argv[i],
"-g")) {
463 usage(use_noarg, argv[i-1]);
465 }
else if (!strcmp(argv[i],
"-nw")) {
467 }
else if (!strcmp(argv[i],
"-n")) {
470 }
else if (!strcmp(argv[i],
"-w")) {
473 }
else if (!strcmp(argv[i],
"-e")) {
476 usage(use_noarg, argv[i-1]);
477 tmp =
dmalloc(strlen(argv[i]) +
sizeof *tmp,
MDL);
485 }
else if (!strcmp(argv[i],
"-S")) {
487 usage(use_v6command, argv[i]);
489 local_family_set = 1;
493 }
else if (!strcmp(argv[i],
"-N")) {
495 usage(use_v6command, argv[i]);
497 local_family_set = 1;
503 }
else if (!strcmp(argv[i],
"-T")) {
505 usage(use_v6command, argv[i]);
507 local_family_set = 1;
513 }
else if (!strcmp(argv[i],
"-P")) {
515 usage(use_v6command, argv[i]);
517 local_family_set = 1;
523 }
else if (!strcmp(argv[i],
"-R")) {
525 usage(use_v6command, argv[i]);
527 local_family_set = 1;
530 }
else if (!strcmp(argv[i],
"--dad-wait-time")) {
532 usage(use_noarg, argv[i-1]);
535 dad_wait_time = (
int)strtol(argv[i], &s, 10);
536 if (errno || (*s !=
'\0') || (dad_wait_time < 0)) {
537 usage(
"Invalid value for --dad-wait-time: %s",
540 }
else if (!strcmp(argv[i],
"--prefix-len-hint")) {
542 usage(use_noarg, argv[i-1]);
546 prefix_len_hint = (
int)strtol(argv[i], &s, 10);
547 if (errno || (*s !=
'\0') || (prefix_len_hint < 0)) {
548 usage(
"Invalid value for --prefix-len-hint: %s",
551 }
else if (!strcmp(argv[i],
"--address-prefix-len")) {
553 usage(use_noarg, argv[i-1]);
557 if (errno || (*s !=
'\0') ||
559 usage(
"Invalid value for"
560 " --address-prefix-len: %s", argv[i]);
563 }
else if (!strcmp(argv[i],
"--decline-wait-time")) {
565 usage(use_noarg, argv[i-1]);
570 if (errno || (*s !=
'\0') ||
572 usage(
"Invalid value for "
573 "--decline-wait-time: %s", argv[i]);
575 }
else if (!strcmp(argv[i],
"-D")) {
578 usage(use_noarg, argv[i-1]);
579 if (!strcasecmp(argv[i],
"LL")) {
581 }
else if (!strcasecmp(argv[i],
"LLT")) {
584 usage(
"Unknown argument to -D: %s", argv[i]);
586 }
else if (!strcmp(argv[i],
"-i")) {
589 }
else if (!strcmp(argv[i],
"-I")) {
592 }
else if (!strcmp(argv[i],
"-v")) {
594 }
else if (!strcmp(argv[i],
"-C")) {
595 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
596 usage(use_noarg, argv[i-1]);
605 dhcp_client_identifier_arg = argv[i];
606 }
else if (!strcmp(argv[i],
"-B")) {
608 }
else if (!strcmp(argv[i],
"-H")) {
609 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
610 usage(use_noarg, argv[i-1]);
619 if (dhcp_host_name_arg != NULL) {
620 log_error(
"The -H <host-name> and -F <fqdn> arguments are mutually exclusive");
624 dhcp_host_name_arg = argv[i];
625 }
else if (!strcmp(argv[i],
"-F")) {
626 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
627 usage(use_noarg, argv[i-1]);
636 if (dhcp_fqdn_arg != NULL) {
637 log_error(
"Only one -F <fqdn> argument can be specified");
641 if (dhcp_host_name_arg != NULL) {
642 log_error(
"The -F <fqdn> and -H <host-name> arguments are mutually exclusive");
646 dhcp_fqdn_arg = argv[i];
647 }
else if (!strcmp(argv[i],
"--timeout")) {
648 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
649 usage(use_noarg, argv[i-1]);
653 if ((timeout_arg = atoi(argv[i])) <= 0) {
654 log_error(
"timeout option must be > 0 - bad value: %s",argv[i]);
657 }
else if (!strcmp(argv[i],
"-V")) {
658 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
659 usage(use_noarg, argv[i-1]);
668 dhcp_vendor_class_identifier_arg = argv[i];
669 }
else if (!strcmp(argv[i],
"--request-options")) {
670 if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])==
'\0')) {
671 usage(use_noarg, argv[i-1]);
675 dhclient_request_options = argv[i];
677 }
else if (!strcmp(argv[i],
"-nc")) {
678 #ifdef HAVE_LIBCAP_NG
679 keep_capabilities = 1;
681 }
else if (argv[i][0] ==
'-') {
682 usage(
"Unknown command: %s", argv[i]);
684 usage(
"No interfaces comamnd -n and "
685 " requested interface %s", argv[i]);
689 status = interface_allocate(&tmp,
MDL);
691 log_fatal(
"Can't record interface %s:%s",
692 argv[i], isc_result_totext(status));
693 if (strlen(argv[i]) >=
sizeof(tmp->
name))
694 log_fatal(
"%s: interface name too long (is %ld)",
695 argv[i], (
long)strlen(argv[i]));
698 interface_reference(&tmp->
next,
714 usage(
"PD %s only supports one requested interface",
"-P");
717 #if defined(DHCPv6) && defined(DHCP4o6)
719 (exit_mode || release_mode))
720 log_error(
"Can't relay DHCPv4-over-DHCPv6 "
721 "without a persistent DHCPv6 client");
724 log_fatal(
"DHCPv4-over-DHCPv6 requires an explicit "
725 "interface on which to be applied");
728 if (!no_dhclient_conf && (s = getenv(
"PATH_DHCLIENT_CONF"))) {
731 if (!no_dhclient_db && (s = getenv(
"PATH_DHCLIENT_DB"))) {
734 if (!no_dhclient_pid && (s = getenv(
"PATH_DHCLIENT_PID"))) {
737 if (!no_dhclient_script && (s = getenv(
"PATH_DHCLIENT_SCRIPT"))) {
741 #ifdef HAVE_LIBCAP_NG
743 if (!keep_capabilities) {
744 capng_clear(CAPNG_SELECT_CAPS);
745 capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
747 capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
748 CAP_NET_ADMIN, CAP_NET_RAW,
749 CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1);
750 capng_apply(CAPNG_SELECT_CAPS);
788 if ((release_mode || exit_mode) && (
no_pid_file == ISC_FALSE)) {
795 e = fscanf(pidfd,
"%ld\n", &temp);
796 oldpid = (pid_t)temp;
798 if (e != 0 && e != EOF && oldpid) {
799 if (kill(oldpid, SIGTERM) == 0) {
800 log_info(
"Killed old client process");
810 }
else if (errno == ESRCH) {
824 char *new_path_dhclient_pid;
843 int n_len = strlen(ip->
name);
845 new_path_dhclient_pid = (
char*) malloc(pfx + n_len + 6);
847 sprintf(new_path_dhclient_pid + pfx,
"-%s.pid", ip->
name);
849 if ((pidfd = fopen(new_path_dhclient_pid,
"re")) != NULL) {
850 e = fscanf(pidfd,
"%ld\n", &temp);
851 oldpid = (pid_t)temp;
853 if (e != 0 && e != EOF) {
855 if (kill(oldpid, SIGTERM) == 0)
863 free(new_path_dhclient_pid);
872 char procfn[256] =
"";
875 if ((fscanf(pidfp,
"%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
876 snprintf(procfn,256,
"/proc/%u",dhcpid);
877 dhc_running = (access(procfn, F_OK) == 0);
884 log_fatal(
"dhclient(%u) is already running - exiting. ", dhcpid);
909 memcpy(&
giaddr, he->h_addr_list[0],
918 gettimeofday(&
cur_tv, NULL);
925 he = gethostbyname(server);
945 usage(
"Stateless command: %s incompatibile with "
946 "other commands",
"-S");
948 #if defined(DHCPv6) && defined(DHCP4o6)
963 if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg !=
'\0')) {
964 arg_conf_len =
asprintf(&arg_conf,
"send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);
966 if ((arg_conf == 0) || (arg_conf_len <= 0))
967 log_fatal(
"Unable to send -C option dhcp-client-identifier");
970 if ((dhcp_host_name_arg != NULL) && (*dhcp_host_name_arg !=
'\0')) {
972 arg_conf_len =
asprintf(&arg_conf,
"send host-name \"%s\";", dhcp_host_name_arg);
974 if ((arg_conf == 0) || (arg_conf_len <= 0))
975 log_fatal(
"Unable to send -H option host-name");
977 char *last_arg_conf = arg_conf;
979 arg_conf_len =
asprintf(&arg_conf,
"%s\nsend host-name \"%s\";", last_arg_conf, dhcp_host_name_arg);
981 if ((arg_conf == 0) || (arg_conf_len <= 0))
982 log_fatal(
"Unable to send -H option host-name");
988 if ((dhcp_fqdn_arg != NULL) && (*dhcp_fqdn_arg !=
'\0')) {
990 arg_conf_len =
asprintf(&arg_conf,
"send fqdn.fqdn \"%s\";", dhcp_fqdn_arg);
992 if ((arg_conf == 0) || (arg_conf_len <= 0))
993 log_fatal(
"Unable to send -F option fqdn.fqdn");
995 char *last_arg_conf = arg_conf;
997 arg_conf_len =
asprintf(&arg_conf,
"%s\nsend fqdn.fqdn \"%s\";", last_arg_conf, dhcp_fqdn_arg);
999 if ((arg_conf == 0) || (arg_conf_len <= 0))
1000 log_fatal(
"Unable to send -F option fqdn.fqdn");
1002 free(last_arg_conf);
1007 if (arg_conf == 0) {
1008 arg_conf_len =
asprintf(&arg_conf,
"timeout %d;", timeout_arg);
1010 if ((arg_conf == 0) || (arg_conf_len <= 0))
1011 log_fatal(
"Unable to process --timeout timeout argument");
1013 char *last_arg_conf = arg_conf;
1015 arg_conf_len =
asprintf(&arg_conf,
"%s\ntimeout %d;", last_arg_conf, timeout_arg);
1017 if ((arg_conf == 0) || (arg_conf_len == 0))
1018 log_fatal(
"Unable to process --timeout timeout argument");
1020 free(last_arg_conf);
1024 if ((dhcp_vendor_class_identifier_arg != NULL) && (*dhcp_vendor_class_identifier_arg !=
'\0')) {
1025 if (arg_conf == 0) {
1026 arg_conf_len =
asprintf(&arg_conf,
"send vendor-class-identifier \"%s\";", dhcp_vendor_class_identifier_arg);
1028 if ((arg_conf == 0) || (arg_conf_len <= 0))
1029 log_fatal(
"Unable to send -V option vendor-class-identifier");
1031 char *last_arg_conf = arg_conf;
1033 arg_conf_len =
asprintf(&arg_conf,
"%s\nsend vendor-class-identifier \"%s\";", last_arg_conf, dhcp_vendor_class_identifier_arg);
1035 if ((arg_conf == 0) || (arg_conf_len <= 0))
1036 log_fatal(
"Unable to send -V option vendor-class-identifier");
1038 free(last_arg_conf);
1042 if (dhclient_request_options != NULL) {
1043 if (arg_conf == 0) {
1044 arg_conf_len =
asprintf(&arg_conf,
"request %s;", dhclient_request_options);
1046 if ((arg_conf == 0) || (arg_conf_len <= 0))
1047 log_fatal(
"Unable to parse --request-options <request options list> argument");
1049 char *last_arg_conf = arg_conf;
1051 arg_conf_len =
asprintf(&arg_conf,
"%s\nrequest %s;", last_arg_conf, dhclient_request_options);
1053 if ((arg_conf == 0) || (arg_conf_len <= 0))
1054 log_fatal(
"Unable to parse --request-options <request options list> argument");
1056 free(last_arg_conf);
1061 if (arg_conf_len == 0)
1062 if ((arg_conf_len = strlen(arg_conf)) == 0)
1064 log_fatal(
"Unable to process -C/-H/-F/--timeout/-V/--request-options configuration arguments");
1069 const char *
val = NULL;
1072 status =
new_parse(&cfile, -1, arg_conf, arg_conf_len,
"extra dhclient -C/-H/-F/--timeout/-V/--request-options configuration arguments", 0);
1075 log_fatal(
"Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
1079 token =
peek_token(&val, (
unsigned *)0, cfile);
1087 log_fatal(
"Cannot parse -C/-H/-F/--timeout/-V/--request-options configuration arguments !");
1144 log_info(
"No broadcast interfaces found - exiting.");
1147 }
else if (!release_mode && !exit_mode) {
1181 unsigned backup_seed = 0;
1184 if ( ip -> hw_address.hlen <=
sizeof seed )
1187 &ip -> hw_address.hbuf [ip -> hw_address.hlen -
1188 sizeof seed],
sizeof seed);
1210 if ( ip -> hw_address.hlen <=
sizeof seed )
1214 sizeof seed],
sizeof seed);
1218 if ( seed_flag == 0 ) {
1219 if ( backup_seed != 0 ) {
1221 log_info (
"xid: rand init seed (0x%x) built using all"
1222 " available interfaces",seed);
1225 seed =
cur_time^((unsigned) gethostid()) ;
1226 log_info (
"xid: warning: no netdev with useable HWADDR found"
1227 " for seed's uniqueness enforcement");
1228 log_info (
"xid: rand init seed (0x%x) built using gethostid",
1233 srandom(seed + ((
unsigned)(
cur_tv.tv_usec * 1000000)) + (
unsigned)getpid());
1236 srandom(seed + ((
unsigned)(
cur_tv.tv_usec * 1000000)) + (
unsigned)getpid());
1242 setup_ib_interface(ip);
1261 #if defined(DHCPv6) && defined(DHCP4o6)
1263 dhcp4o6_setup(dhcp4o6_port);
1270 for (client = ip->
client ; client != NULL ;
1271 client = client->
next) {
1275 }
else if (exit_mode) {
1295 for (client = ip->
client ; client ;
1296 client = client->
next) {
1313 tv.tv_usec = random()
1349 log_fatal(
"Can't allocate new generic object: %s\n",
1350 isc_result_totext(result));
1356 log_fatal(
"Can't start OMAPI protocol: %s",
1357 isc_result_totext (result));
1366 #if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
1367 defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1368 dmalloc_cutoff_generation = dmalloc_generation;
1369 dmalloc_longterm = dmalloc_outstanding;
1370 dmalloc_outstanding = 0;
1373 #if defined(ENABLE_GENTLE_SHUTDOWN)
1410 isc_result_t result;
1420 usage(
"No interfaces available for stateless command: %s",
"-S");
1452 dhcp4o6_setup(port);
1458 client = client->
next) {
1473 log_fatal(
"Can't allocate new generic object: %s\n",
1474 isc_result_totext(result));
1480 log_fatal(
"Can't start OMAPI protocol: %s",
1481 isc_result_totext(result));
1487 #if defined(DEBUG_MEMORY_LEAKAGE) || defined(DEBUG_MALLOC_POOL) || \
1488 defined(DEBUG_MEMORY_LEAKAGE_ON_EXIT)
1489 dmalloc_cutoff_generation = dmalloc_generation;
1490 dmalloc_longterm = dmalloc_outstanding;
1491 dmalloc_outstanding = 0;
1513 const char *s,
const char *
file,
int line)
1557 "dhcp-client-identifier") == 0)) {
1563 log_fatal(
"dhcp-client-identifier must be specified for InfiniBand");
1600 #if defined(DHCPv6) && defined(DHCP4o6)
1602 if (dhcp4o6_state < 0)
1613 client ->
active -> is_bootp ||
1627 client ->
xid = random ();
1696 for (lp = client -> offered_leases; lp; lp =
next) {
1705 picked -> next = NULL;
1710 client -> offered_leases = NULL;
1717 client -> state =
S_INIT;
1724 client ->
new = picked;
1742 client -> first_sending =
cur_time;
1743 client -> interval = client -> config -> initial_interval;
1747 client -> xid = client ->
packet.xid;
1770 for (client = ip -> client; client; client = client -> next) {
1771 if (client -> xid == packet -> raw -> xid)
1775 (packet -> interface -> hw_address.hlen - 1 !=
1776 packet -> raw -> hlen) ||
1777 (memcmp (&packet -> interface -> hw_address.hbuf [1],
1778 packet -> raw -> chaddr, packet -> raw -> hlen))) {
1780 log_debug (
"DHCPACK in wrong transaction.");
1794 log_info (
"DHCPACK of %s from %s (xid=0x%x)",
1795 inet_ntoa(packet->raw->yiaddr),
1796 piaddr (packet -> client_addr),
1797 ntohl(client -> xid));
1801 log_info (
"packet_to_lease failed.");
1805 client ->
new = lease;
1813 memset (&ds, 0,
sizeof ds);
1816 packet -> options, client ->
new -> options,
1821 client ->
new -> expiry = 0;
1824 client ->
new -> expiry = 0;
1829 log_error (
"no expiry time on offered lease.");
1835 tv.tv_sec =
cur_tv.tv_sec;
1836 tv.tv_usec =
cur_tv.tv_usec + 500000;
1838 if (tv.tv_usec >= 1000000) {
1840 tv.tv_usec -= 1000000;
1859 packet -> options, client ->
new -> options,
1864 client ->
new -> renewal = 0;
1867 client ->
new -> renewal = 0;
1870 if (!client ->
new -> renewal)
1871 client ->
new -> renewal = client ->
new -> expiry / 2 + 1;
1873 if (client ->
new -> renewal <= 0)
1874 client ->
new -> renewal =
TIME_MAX;
1879 (((random() % client->
new->
renewal) + 3) / 4);
1886 packet -> options, client ->
new -> options,
1891 client ->
new -> rebind = 0;
1894 client ->
new -> rebind = 0;
1896 if (client ->
new -> rebind <= 0) {
1897 if (client ->
new -> expiry <=
TIME_MAX / 7)
1898 client ->
new -> rebind =
1899 client ->
new -> expiry * 7 / 8;
1901 client ->
new -> rebind =
1902 client ->
new -> expiry / 8 * 7;
1907 if (client ->
new -> renewal > client ->
new -> rebind) {
1908 if (client ->
new -> rebind <=
TIME_MAX / 3)
1909 client ->
new -> renewal =
1910 client ->
new -> rebind * 3 / 4;
1912 client ->
new -> renewal =
1913 client ->
new -> rebind / 4 * 3;
1916 client ->
new -> expiry +=
cur_time;
1918 if (client ->
new -> expiry <
cur_time)
1919 client ->
new -> expiry =
TIME_MAX;
1920 client ->
new -> renewal +=
cur_time;
1921 if (client ->
new -> renewal <
cur_time)
1922 client ->
new -> renewal =
TIME_MAX;
1923 client ->
new -> rebind +=
cur_time;
1924 if (client ->
new -> rebind <
cur_time)
1925 client ->
new -> rebind =
TIME_MAX;
1943 client->new->medium);
1944 if (client->active && client->state !=
S_REBOOTING)
1961 log_info(
"Unable to obtain a lease on first "
1962 "try (declined). Exiting.");
1965 #if defined (CALL_SCRIPT_ON_ONETRY_FAIL)
1974 tv.tv_usec =
cur_tv.tv_usec;
1981 if (!client->last_write ||
1988 client->active = client->new;
1992 tv.tv_sec = client->active->renewal;
1993 tv.tv_usec = ((client->active->renewal -
cur_tv.tv_sec) > 1) ?
1994 random() % 1000000 :
cur_tv.tv_usec;
1997 log_info(
"bound to %s -- renewal in %ld seconds.",
1998 piaddr(client->active->address),
1999 (
long)(client->active->renewal -
cur_time));
2003 #if defined (NSUPDATE)
2004 if (client->config->do_forward_update)
2025 client -> xid = client ->
packet.xid;
2027 memset (&ds, 0,
sizeof ds);
2033 client -> active -> options,
2036 memcpy (client -> destination.iabuf, ds.
data, 4);
2037 client -> destination.len = 4;
2045 client -> first_sending =
cur_time;
2046 client -> interval = client -> config -> initial_interval;
2114 for (ap = packet -> interface -> client -> config -> reject_list;
2115 ap; ap = ap ->
next) {
2124 log_info(
"BOOTREPLY from %s rejected by rule %s "
2125 "mask %s.",
piaddr(packet->client_addr),
2139 void (*handler) (
struct packet *);
2166 for (ap = packet ->
interface -> client -> config -> reject_list;
2167 ap; ap = ap -> next) {
2176 log_info(
"%s from %s rejected by rule %s mask %s.",
2177 type,
piaddr(packet->client_addr),
2182 (*handler) (packet);
2190 char addrbuf[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")];
2198 ap ; ap = ap->
next) {
2201 log_info(
"%s from %s rejected by rule %s",
2214 log_info(
"RCV: %s message on %s from %s.",
2218 forw_dhcpv4_response(packet);
2228 log_info(
"RCV: %s message on %s from %s.",
2239 client = client->
next) {
2248 log_info(
"Packet received, but nothing done with it.");
2264 static void forw_dhcpv4_response(
struct packet *packet)
2274 if (dhcp4o6_state == -1) {
2275 log_info(
"forw_dhcpv4_response: not ready.");
2280 log_error(
"forw_dhcpv4_response: bad address");
2289 log_info(
"DHCPv4-response from %s missing "
2290 "DHCPv4 Message option.",
2295 memset(&enc_opt_data, 0,
sizeof(enc_opt_data));
2298 log_error(
"forw_dhcpv4_response: error evaluating "
2306 "no memory for encapsulated packet.");
2314 memset(&ds, 0,
sizeof(ds));
2316 log_error(
"forw_dhcpv4_response: no memory buffer.");
2320 ds.data = ds.buffer->data;
2321 ds.len = enc_opt_data.len + 16;
2322 memcpy(ds.buffer->data, enc_opt_data.data, enc_opt_data.len);
2323 memcpy(ds.buffer->data + enc_opt_data.len,
2330 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
2332 log_error(
"forw_dhcpv4_response: send(): %m");
2346 static void recv_dhcpv4_response(
struct data_string *raw)
2348 struct packet *packet;
2352 log_error(
"recv_dhcpv4_response: no interfaces.");
2357 memcpy(from.iabuf, raw->
data + (raw->
len - 16), 16);
2364 log_error(
"recv_dhcpv4_response: no memory for packet.");
2376 log_error(
"recv_dhcpv4_response: no memory for options.");
2397 memset(&dp, 0,
sizeof dp);
2423 struct packet *packet;
2431 const char *
name = packet -> packet_type ?
"DHCPOFFER" :
"BOOTREPLY";
2440 for (client = ip -> client; client; client = client -> next)
2441 if (client -> xid == packet -> raw -> xid)
2448 (packet -> interface -> hw_address.hlen - 1 !=
2449 packet -> raw -> hlen) ||
2450 (memcmp (&packet -> interface -> hw_address.hbuf [1],
2451 packet -> raw -> chaddr, packet -> raw -> hlen))) {
2453 log_debug (
"%s in wrong transaction.", name);
2458 sprintf (obuf,
"%s of %s from %s", name,
2459 inet_ntoa(packet->raw->yiaddr),
2460 piaddr(packet->client_addr));
2467 for (i = 0 ; req[i] != NULL ; i++) {
2474 option_code_hash_lookup(&option,
2479 log_info(
"%s: no %s option.", obuf,
2482 log_info(
"%s: no unknown-%u option.",
2493 for (lease = client -> offered_leases; lease; lease = lease -> next) {
2494 if (lease -> address.len ==
sizeof packet -> raw -> yiaddr &&
2495 !memcmp (lease -> address.iabuf,
2496 &packet -> raw -> yiaddr, lease -> address.len)) {
2504 log_info (
"%s: packet_to_lease failed.", obuf);
2513 if (!packet -> options_valid || !packet -> packet_type)
2514 lease -> is_bootp = 1;
2517 lease -> medium = client -> medium;
2520 stop_selecting = (client -> first_sending +
2521 client -> config -> select_interval);
2525 if (lease -> address.len == client -> requested_address.len &&
2526 !memcmp (lease -> address.iabuf,
2527 client -> requested_address.iabuf,
2528 client -> requested_address.len)) {
2529 lease -> next = client -> offered_leases;
2530 client -> offered_leases = lease;
2534 if (!client -> offered_leases)
2535 client -> offered_leases = lease;
2537 for (lp = client -> offered_leases; lp ->
next;
2547 if (stop_selecting <=
cur_tv.tv_sec)
2550 tv.tv_sec = stop_selecting;
2551 tv.tv_usec =
cur_tv.tv_usec;
2561 struct packet *packet;
2573 log_error(
"packet_to_lease: no memory to record lease.\n");
2577 memset(lease, 0,
sizeof(*lease));
2582 lease->address.len =
sizeof(packet->raw->yiaddr);
2583 memcpy(lease->address.iabuf, &packet->raw->yiaddr,
2584 lease->address.len);
2586 lease->next_srv_addr.len =
sizeof(packet->raw->siaddr);
2587 memcpy(lease->next_srv_addr.iabuf, &packet->raw->siaddr,
2588 lease->next_srv_addr.len);
2590 memset(&data, 0,
sizeof(data));
2592 if (client -> config -> vendor_space_name) {
2598 client -> config -> vendor_space_name &&
2600 (
struct lease *)0, client,
2604 if (!option_code_hash_lookup(&option,
2608 "option (%s:%d).",
MDL);
2612 client -> config -> vendor_space_name
2638 if (!(i & 2) && packet -> raw -> sname [0]) {
2642 if (!packet -> raw -> sname [len])
2646 log_error (
"dhcpoffer: no memory for server name.\n");
2651 packet -> raw -> sname, len);
2657 if (!(i & 1) && packet -> raw ->
file [0]) {
2661 if (!packet -> raw ->
file [len])
2665 log_error (
"dhcpoffer: no memory for filename.\n");
2670 packet -> raw ->
file, len);
2676 client, lease->options, lease->options,
2684 struct packet *packet;
2690 for (client = ip -> client; client; client = client ->
next)
2691 if (client ->
xid == packet -> raw ->
xid)
2697 (packet ->
interface -> hw_address.hlen - 1 !=
2698 packet -> raw -> hlen) ||
2699 (memcmp (&packet ->
interface -> hw_address.hbuf [1],
2700 packet -> raw -> chaddr, packet -> raw -> hlen))) {
2702 log_debug (
"DHCPNAK in wrong transaction.");
2717 log_info (
"DHCPNAK from %s (xid=0x%x)",
piaddr (packet -> client_addr), ntohl(client ->
xid));
2721 log_info (
"DHCPNAK with no active lease.\n");
2754 client -> state =
S_INIT;
2773 interval =
cur_time - client -> first_sending;
2777 if (interval > client -> config ->
timeout) {
2785 if (!client -> offered_leases &&
2786 client -> config -> media) {
2789 if (client -> medium) {
2790 client -> medium = client -> medium -> next;
2793 if (!client -> medium) {
2795 log_fatal (
"No valid media types for %s!",
2796 client -> interface -> name);
2798 client -> config -> media;
2802 log_info (
"Trying medium \"%s\" %d",
2803 client -> medium ->
string, increase);
2831 if (
cur_time + client -> interval >
2832 client -> first_sending + client -> config ->
timeout)
2833 client -> interval =
2834 (client -> first_sending +
2838 if (interval < 65536)
2839 client -> packet.secs = htons (interval);
2841 client -> packet.secs = htons (65535);
2842 client -> secs = client -> packet.secs;
2844 #if defined(DHCPv6) && defined(DHCP4o6)
2846 log_info (
"DHCPDISCOVER interval %ld",
2847 (
long)(client -> interval));
2850 log_info (
"DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
2851 client -> name ? client -> name : client -> interface -> name,
2853 ntohs (
sockaddr_broadcast.sin_port), (
long)(client -> interval), ntohl(client -> xid));
2856 #if defined(DHCPv6) && defined(DHCP4o6)
2858 result = send_dhcpv4_query(client, 1);
2865 #if defined(DHCPv6) && defined(DHCP4o6)
2867 log_error(
"%s:%d: Failed to send %d byte long packet.",
2871 log_error(
"%s:%d: Failed to send %d byte long packet over %s "
2883 tv.tv_usec = client->
interval > 1 ? random() % 1000000 :
cur_tv.tv_usec;
2900 loop = lp = client -> active;
2902 log_info (
"No DHCPOFFERS received.");
2906 if (!client -> active && client -> leases)
2910 while (client -> active) {
2911 if (client -> active -> expiry >
cur_time) {
2912 log_info (
"Trying recorded lease %s",
2913 piaddr (client -> active -> address));
2917 client -> active -> medium);
2920 if (client -> alias)
2928 if (cur_time < client -> active -> renewal) {
2930 log_info (
"bound: renewal in %ld %s.",
2931 (
long)(client -> active -> renewal -
2936 random() % 1000000 :
2941 log_info (
"bound: immediate renewal.");
2951 if (!client -> leases) {
2952 client -> leases = client -> active;
2960 for (lp = client -> leases; lp ->
next; lp = lp ->
next)
2962 lp ->
next = client -> active;
2966 client -> active = client -> leases;
2967 client -> leases = client -> leases ->
next;
2972 if (client -> active == loop)
2975 loop = client -> active;
2983 log_info (
"Unable to obtain a lease on first try.%s",
2987 #if defined (CALL_SCRIPT_ON_ONETRY_FAIL)
2995 log_info (
"No working leases in persistent database - sleeping.");
2997 if (client -> alias)
3000 client -> state =
S_INIT;
3003 tv.tv_usec = ((tv.tv_sec -
cur_tv.tv_sec) > 1) ?
3004 random() % 1000000 :
cur_tv.tv_usec;
3016 struct sockaddr_in destination;
3017 struct in_addr from;
3020 const char* rip_str =
"";
3023 interval =
cur_time - client -> first_sending;
3037 interval > client -> config -> reboot_timeout) {
3039 client -> state =
S_INIT;
3048 !client -> medium &&
3049 client -> active -> medium ) {
3050 script_init(client,
"MEDIUM", client -> active -> medium);
3057 client -> medium = client -> active -> medium;
3063 cur_time > client -> active -> expiry) {
3068 if (client -> alias)
3076 if (client -> alias)
3081 client -> state =
S_INIT;
3087 if (!client -> interval)
3088 client -> interval = client -> config -> initial_interval;
3090 client -> interval += ((random () >> 2) %
3091 (2 * client -> interval));
3095 if (client -> interval >
3096 client -> config -> backoff_cutoff)
3097 client -> interval =
3098 ((client -> config -> backoff_cutoff / 2)
3099 + ((random () >> 2) %
3100 client -> config -> backoff_cutoff));
3105 cur_time + client -> interval > client -> active -> expiry)
3106 client -> interval =
3107 client -> active -> expiry -
cur_time + 1;
3113 cur_time > client -> active -> rebind)
3116 memcpy (&destination.sin_addr.s_addr,
3117 client -> destination.iabuf,
3118 sizeof destination.sin_addr.s_addr);
3120 destination.sin_family = AF_INET;
3122 destination.sin_len =
sizeof destination;
3127 memcpy (&from, client -> active -> address.iabuf,
3130 from.s_addr = INADDR_ANY;
3134 client -> packet.secs = client -> secs;
3136 if (interval < 65536)
3137 client -> packet.secs = htons (interval);
3139 client -> packet.secs = htons (65535);
3142 #if defined(DHCPv6) && defined(DHCP4o6)
3147 memset(rip_buf, 0x0,
sizeof(rip_buf));
3155 strncpy(rip_buf, rip_str,
sizeof(rip_buf)-1);
3156 log_info (
"DHCPREQUEST for %s on %s to %s port %d (xid=0x%x)",
3159 inet_ntoa(destination.sin_addr),
3160 ntohs (destination.sin_port),
3161 ntohl(client -> xid));
3163 #if defined(DHCPv6) && defined(DHCP4o6)
3166 if (destination.sin_addr.s_addr == INADDR_BROADCAST)
3168 result = send_dhcpv4_query(client, broadcast);
3170 log_error(
"%s:%d: Failed to send %d byte long packet.",
3175 if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
3177 #if defined(SO_BINDTODEVICE)
3181 log_error(
"%s:%d: Failed to bind fallback interface"
3189 log_error(
"%s:%d: Failed to send %d byte long packet "
3190 "over %s interface.",
MDL,
3194 #if defined(SO_BINDTODEVICE)
3196 SO_BINDTODEVICE, NULL, 0) < 0) {
3197 log_fatal(
"%s:%d: Failed to unbind fallback interface:"
3208 log_error(
"%s:%d: Failed to send %d byte long packet"
3209 " over %s interface.",
MDL,
3216 tv.tv_usec = ((tv.tv_sec -
cur_tv.tv_sec) > 1) ?
3217 random() % 1000000 :
cur_tv.tv_usec;
3228 #if defined(DHCPv6) && defined(DHCP4o6)
3233 log_info (
"DHCPDECLINE of %s on %s to %s port %d (xid=0x%x)",
3238 ntohl(client ->
xid));
3242 #if defined(DHCPv6) && defined(DHCP4o6)
3244 result = send_dhcpv4_query(client, 1);
3251 #if defined(DHCPv6) && defined(DHCP4o6)
3253 log_error(
"%s:%d: Failed to send %d byte long packet.",
3257 log_error(
"%s:%d: Failed to send %d byte long packet over %s"
3269 struct sockaddr_in destination;
3270 struct in_addr from;
3272 memcpy (&from, client -> active -> address.iabuf,
3274 memcpy (&destination.sin_addr.s_addr,
3275 client -> destination.iabuf,
3276 sizeof destination.sin_addr.s_addr);
3278 destination.sin_family = AF_INET;
3280 destination.sin_len =
sizeof destination;
3285 client -> active -> expiry =
3286 client -> active -> renewal =
3287 client -> active -> rebind =
cur_time;
3289 log_error (
"Can't release lease: lease write failed.");
3293 #if defined(DHCPv6) && defined(DHCP4o6)
3298 log_info (
"DHCPRELEASE of %s on %s to %s port %d (xid=0x%x)",
3301 inet_ntoa (destination.sin_addr),
3302 ntohs (destination.sin_port),
3303 ntohl(client -> xid));
3305 #if defined(DHCPv6) && defined(DHCP4o6)
3308 if (destination.sin_addr.s_addr == INADDR_BROADCAST)
3310 result = send_dhcpv4_query(client, broadcast);
3312 log_error(
"%s:%d: Failed to send %d byte long packet.",
3318 #if defined(SO_BINDTODEVICE)
3322 log_error(
"%s:%d: Failed to bind fallback interface"
3330 log_error(
"%s:%d: Failed to send %d byte long packet"
3331 " over %s interface.",
MDL,
3335 #if defined(SO_BINDTODEVICE)
3337 SO_BINDTODEVICE, NULL, 0) < 0) {
3338 log_fatal(
"%s:%d: Failed to unbind fallback interface:"
3348 log_error (
"%s:%d: Failed to send %d byte long packet"
3349 " over %s interface.",
MDL,
3357 #if defined(DHCPv6) && defined(DHCP4o6)
3369 static int send_dhcpv4_query(
struct client_state *client,
int broadcast) {
3374 if (dhcp4o6_state <= 0) {
3375 log_info(
"send_dhcpv4_query: not ready.");
3385 memset(&ds, 0,
sizeof(ds));
3387 log_error(
"Unable to allocate memory for DHCPv4-query.");
3390 ds.data = ds.buffer->data;
3415 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
3417 log_error(
"send_dhcpv4_query: send(): %m");
3430 static void forw_dhcpv4_query(
struct data_string *raw) {
3436 struct sockaddr_in6 sin6;
3437 int i, send_ret, attempt, success;
3439 attempt = success = 0;
3440 memset(&sin6, 0,
sizeof(sin6));
3441 sin6.sin6_family = AF_INET6;
3444 sin6.sin6_len =
sizeof(sin6);
3446 memset(&addrs, 0,
sizeof(addrs));
3448 for (client = ip->
client; client != NULL;
3449 client = client->
next) {
3455 if ((lease == NULL) || lease->
released)
3464 ((addrs.len %
sizeof(sin6.sin6_addr)) != 0)) {
3468 if (addrs.len == 0) {
3476 if (send_ret == raw->
len)
3480 for (i = 0; i < addrs.len;
3481 i +=
sizeof(sin6.sin6_addr)) {
3482 memcpy(&sin6.sin6_addr, addrs.data + i,
3483 sizeof(sin6.sin6_addr));
3487 if (send_ret == raw->
len)
3494 log_info(
"forw_dhcpv4_query: sent(%d): %d/%d",
3495 raw->
len, success, attempt);
3511 struct buffer *bp = NULL;
3534 log_error (
"can't make requested address cache.");
3560 for (i = 0 ; prl[i] != NULL ; i++)
3565 log_error(
"can't make parameter list buffer.");
3570 for (i = 0 ; prl[i] != NULL ; i++)
3574 if (!(option_code_hash_lookup(&option,
3599 memset(&client_identifier, 0,
sizeof(client_identifier));
3602 client_identifier.
len,
MDL))
3603 log_fatal(
"no memory for default DUID!");
3621 memcpy(&client_identifier.
buffer->
data + 5 - hw_len,
3626 memcpy(&client_identifier.
buffer->
data+(1+4),
3633 (u_int8_t *)client_identifier.
data,
3634 client_identifier.
len,
3636 log_error (
"can't make requested client id cache..");
3647 (lease ? lease->
options : NULL),
3660 memset (&client -> packet, 0,
sizeof (client -> packet));
3664 lease ? &lease -> address : (
struct iaddr *)0,
3665 client -> config -> requested_options,
3669 client -> packet_length =
3671 (
struct lease *)0, client,
3680 client -> config -> vendor_space_name);
3687 client -> packet.htype = client ->
interface -> hw_address.hbuf [0];
3689 client -> packet.hlen = client ->
interface -> hw_address.hlen - 1;
3690 client -> packet.hops = 0;
3691 client -> packet.xid = random ();
3692 client -> packet.secs = 0;
3696 client -> packet.flags = 0;
3700 memset (&(client -> packet.ciaddr),
3701 0,
sizeof client -> packet.ciaddr);
3702 memset (&(client -> packet.yiaddr),
3703 0,
sizeof client -> packet.yiaddr);
3704 memset (&(client -> packet.siaddr),
3705 0,
sizeof client -> packet.siaddr);
3706 client -> packet.giaddr =
giaddr;
3707 if (client -> interface -> hw_address.hlen > 0)
3708 memcpy (client -> packet.chaddr,
3709 &client -> interface -> hw_address.hbuf [1],
3710 (
unsigned)(client -> interface -> hw_address.hlen - 1));
3713 dump_raw ((
unsigned char *)&client -> packet, client -> packet_length);
3725 memset (&client -> packet, 0,
sizeof (client -> packet));
3733 if (client -> sent_options)
3740 : (
struct iaddr *)0),
3741 client -> config -> requested_options,
3742 &client -> sent_options);
3745 client -> packet_length =
3747 (
struct lease *)0, client,
3750 client -> sent_options,
3756 client -> config -> vendor_space_name);
3762 client -> packet.htype = client ->
interface -> hw_address.hbuf [0];
3764 client -> packet.hlen = client ->
interface -> hw_address.hlen - 1;
3765 client -> packet.hops = 0;
3766 client -> packet.xid = client -> xid;
3767 client -> packet.secs = 0;
3771 if (client -> state ==
S_BOUND ||
3774 memcpy (&client -> packet.ciaddr,
3775 lease -> address.iabuf, lease -> address.len);
3776 client -> packet.flags = 0;
3778 memset (&client -> packet.ciaddr, 0,
3779 sizeof client -> packet.ciaddr);
3781 client ->config->bootp_broadcast_always)) &&
3783 client -> packet.flags = 0;
3788 memset (&client -> packet.yiaddr, 0,
3789 sizeof client -> packet.yiaddr);
3790 memset (&client -> packet.siaddr, 0,
3791 sizeof client -> packet.siaddr);
3792 if (client -> state !=
S_BOUND &&
3794 client -> packet.giaddr =
giaddr;
3796 memset (&client -> packet.giaddr, 0,
3797 sizeof client -> packet.giaddr);
3798 if (client -> interface -> hw_address.hlen > 0)
3799 memcpy (client -> packet.chaddr,
3800 &client -> interface -> hw_address.hbuf [1],
3801 (
unsigned)(client -> interface -> hw_address.hlen - 1));
3804 dump_raw ((
unsigned char *)&client -> packet, client -> packet_length);
3824 memset (&client -> packet, 0,
sizeof (client -> packet));
3825 client -> packet_length =
3827 (
struct lease *)0, client, 0,
3830 client -> config -> vendor_space_name);
3839 client -> packet.htype = client ->
interface -> hw_address.hbuf [0];
3841 client -> packet.hlen = client ->
interface -> hw_address.hlen - 1;
3842 client -> packet.hops = 0;
3843 client -> packet.xid = client -> xid;
3844 client -> packet.secs = 0;
3847 client -> packet.flags = 0;
3852 memset (&client -> packet.ciaddr, 0,
3853 sizeof client -> packet.ciaddr);
3854 memset (&client -> packet.yiaddr, 0,
3855 sizeof client -> packet.yiaddr);
3856 memset (&client -> packet.siaddr, 0,
3857 sizeof client -> packet.siaddr);
3858 client -> packet.giaddr =
giaddr;
3859 memcpy (client -> packet.chaddr,
3860 &client -> interface -> hw_address.hbuf [1],
3861 client -> interface -> hw_address.hlen);
3864 dump_raw ((
unsigned char *)&client -> packet, client -> packet_length);
3877 memset (&client -> packet, 0,
sizeof (client -> packet));
3884 client -> packet_length =
3886 (
struct lease *)0, client,
3895 client -> config -> vendor_space_name);
3902 client -> packet.htype = client ->
interface -> hw_address.hbuf [0];
3904 client -> packet.hlen = client ->
interface -> hw_address.hlen - 1;
3905 client -> packet.hops = 0;
3906 client -> packet.xid = random ();
3907 client -> packet.secs = 0;
3908 client -> packet.flags = 0;
3909 memcpy (&client -> packet.ciaddr,
3910 lease -> address.iabuf, lease -> address.len);
3911 memset (&client -> packet.yiaddr, 0,
3912 sizeof client -> packet.yiaddr);
3913 memset (&client -> packet.siaddr, 0,
3914 sizeof client -> packet.siaddr);
3915 client -> packet.giaddr =
giaddr;
3916 memcpy (client -> packet.chaddr,
3917 &client -> interface -> hw_address.hbuf [1],
3918 client -> interface -> hw_address.hlen);
3921 dump_raw ((
unsigned char *)&client -> packet, client -> packet_length);
3928 if (lease -> server_name)
3930 if (lease -> filename)
3945 if (leaseFile != NULL)
3948 if (leaseFile == NULL) {
3960 for (client = ip -> client; client; client = client ->
next) {
3961 for (lp = client -> leases; lp; lp = lp ->
next) {
3964 if (client -> active)
3966 client -> active, 1, 0);
3981 for (client = ip -> client; client; client = client ->
next) {
3982 for (lp = client -> leases; lp; lp = lp ->
next) {
3985 if (client -> active)
3987 client -> active, 1, 0);
4002 struct packet *packet,
struct lease *lease,
4009 const char *name, *dot;
4011 char *preamble = stuff;
4013 memset (&ds, 0,
sizeof ds);
4023 in_options, cfg_options, scope, oc,
MDL)) {
4025 fprintf(leaseFile,
"%soption %s%s%s", preamble,
4031 fprintf(leaseFile,
" %s",
4037 fprintf(leaseFile,
";\n");
4046 const char *preamble)
4059 if (c >=
'0' && c <=
'9')
4062 if (c >=
'a' && c <=
'f')
4063 return c -
'a' + 10;
4065 if (c >=
'A' && c <=
'F')
4066 return c -
'A' + 10;
4073 const char *id_fname =
"/etc/machine-id";
4076 FILE *
file = fopen( id_fname ,
"r");
4079 return ISC_R_IOERROR;
4081 nread = fread(
id, 1,
sizeof id, file);
4085 log_debug(
"Not enough data in %s", id_fname);
4086 return ISC_R_IOERROR;
4089 for (j = 0; j < 16; j++) {
4095 if (a < 0 || b < 0) {
4096 log_debug(
"Wrong data in %s", id_fname);
4097 return ISC_R_IOERROR;
4099 uuid[j] = a << 4 | b;
4103 uuid[6] = (uuid[6] & 0x0F) | 0x40;
4105 uuid[8] = (uuid[8] & 0x3F) | 0x80;
4140 log_debug(
"Cannot form default DUID from interface %s.", ip->
name);
4144 return ISC_R_UNEXPECTED;
4149 log_fatal(
"Impossible hardware address length at %s:%d.",
MDL);
4159 len = 2 +
sizeof (uuid);
4173 log_fatal(
"no memory for default DUID!");
4179 memcpy(duid->
buffer->
data + 2, uuid,
sizeof(uuid));
4199 log_info(
"form_duid: Couldn't allocate memory to log duid!");
4215 if ((duid == NULL) || (duid->
len <= 2))
4218 if (leaseFile == NULL) {
4220 if (leaseFile == NULL) {
4222 return ISC_R_IOERROR;
4230 return ISC_R_NOMEMORY;
4232 stat = fprintf(leaseFile,
"default-duid %s;\n", str);
4235 return ISC_R_IOERROR;
4237 if (fflush(leaseFile) != 0)
4238 return ISC_R_IOERROR;
4246 int rewrite,
int sync)
4254 if (!rewrite && (leases_written++ > 20)) {
4260 if (client == NULL || lease == NULL)
4263 if (leaseFile == NULL) {
4265 if (leaseFile == NULL) {
4267 return ISC_R_IOERROR;
4271 stat = fprintf(leaseFile,
"lease6 {\n");
4273 return ISC_R_IOERROR;
4275 stat = fprintf(leaseFile,
" interface \"%s\";\n",
4278 return ISC_R_IOERROR;
4280 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
4301 (
const unsigned char *) &ia->
iaid, 4,
4306 return ISC_R_IOERROR;
4309 stat = fprintf(leaseFile,
" %s %s {\n",
4317 stat = fprintf(leaseFile,
" %s %s {\n", ianame,
4323 return ISC_R_IOERROR;
4326 stat = fprintf(leaseFile,
" starts %d;\n"
4331 stat = fprintf(leaseFile,
" starts %d;\n",
4334 return ISC_R_IOERROR;
4336 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4338 stat = fprintf(leaseFile,
4342 stat = fprintf(leaseFile,
4343 " iaprefix %s/%d {\n",
4347 return ISC_R_IOERROR;
4349 stat = fprintf(leaseFile,
" starts %d;\n"
4350 " preferred-life %u;\n"
4355 return ISC_R_IOERROR;
4358 write_options(client, addr->
options,
" ");
4360 stat = fprintf(leaseFile,
" }\n");
4362 return ISC_R_IOERROR;
4366 write_options(client, ia->
options,
" ");
4368 stat = fprintf(leaseFile,
" }\n");
4370 return ISC_R_IOERROR;
4374 stat = fprintf(leaseFile,
" released;\n");
4376 return ISC_R_IOERROR;
4380 write_options(client, lease->
options,
" ");
4382 stat = fprintf(leaseFile,
"}\n");
4384 return ISC_R_IOERROR;
4386 if (fflush(leaseFile) != 0)
4387 return ISC_R_IOERROR;
4390 if (fsync(fileno(leaseFile)) < 0) {
4391 log_error(
"write_client_lease: fsync(): %m");
4392 return ISC_R_IOERROR;
4411 if (leases_written++ > 20) {
4419 if (lease -> is_static)
4422 if (leaseFile == NULL) {
4424 if (leaseFile == NULL) {
4431 fprintf (leaseFile,
"lease {\n");
4432 if (lease -> is_bootp) {
4433 fprintf (leaseFile,
" bootp;\n");
4439 fprintf (leaseFile,
" interface \"%s\";\n",
4440 client -> interface -> name);
4445 if (client -> name) {
4446 fprintf (leaseFile,
" name \"%s\";\n", client -> name);
4452 fprintf (leaseFile,
" fixed-address %s;\n",
4453 piaddr (lease -> address));
4458 if (lease -> filename) {
4461 fprintf (leaseFile,
" filename \"%s\";\n", s);
4474 fprintf(leaseFile,
" server-name \"%s\";\n", s);
4483 if (lease -> medium) {
4486 fprintf (leaseFile,
" medium \"%s\";\n", s);
4500 memset (&ds, 0,
sizeof ds);
4502 write_options(client, lease->
options,
" ");
4506 fprintf(leaseFile,
" renew %s\n", tval) < 0)
4511 fprintf(leaseFile,
" rebind %s\n", tval) < 0)
4516 fprintf(leaseFile,
" expire %s\n", tval) < 0)
4519 if (fprintf(leaseFile,
"}\n") < 0)
4522 if (fflush(leaseFile) != 0)
4527 if (!errors && makesure) {
4528 if (fsync (fileno (leaseFile)) < 0) {
4529 log_info (
"write_client_lease: %m");
4534 return errors ? 0 : 1;
4561 for (sl = client -> env; sl; sl =
next) {
4568 if (client -> interface) {
4570 client -> interface -> name);
4574 "",
"client",
"%s", client -> name);
4577 "",
"medium",
"%s", medium ->
string);
4580 client_envadd (client,
"",
"pid",
"%ld", (
long int)getpid ());
4583 (
long int)dad_wait_time);
4589 struct packet *packet,
struct lease *lease,
4598 memset (&data, 0,
sizeof data);
4601 in_options, cfg_options, scope, oc,
MDL)) {
4611 length = strlen(value);
4615 value, length) == 0) {
4620 "option - discarded",
4660 prefix,
"ip_address",
"%s",
piaddr (lease -> address));
4676 memset (&data, 0,
sizeof data);
4679 (
struct lease *)0, client,
4684 struct iaddr netmask, subnet, broadcast;
4707 (&data, (
struct packet *)0,
4708 (
struct lease *)0, client,
4713 if (broadcast.
len) {
4715 prefix,
"broadcast_address",
4716 "%s",
piaddr (broadcast));
4732 "option - discarded",
4745 "option - discarded",
4759 (
unsigned long)(lease -> expiry));
4781 for (i = 0 ; req[i] != NULL ; i++) {
4806 char reason [] =
"REASON=NBI";
4807 static char client_path [] = CLIENT_PATH;
4810 int pid, wpid, wstatus;
4813 scriptName = client -> config -> script_name;
4817 envp =
dmalloc (((client ? client -> envc : 2) +
4820 log_error (
"No memory for client script environment.");
4826 for (sp = client_env; sp; sp = sp ->
next) {
4827 envp [i++] = sp ->
string;
4831 for (sp = client -> env; sp; sp = sp ->
next) {
4832 envp [i++] = sp ->
string;
4835 envp [i++] = reason;
4838 envp [i++] = client_path;
4839 envp [i] = (
char *)0;
4842 argv [1] = (
char *)0;
4850 wpid = wait (&wstatus);
4851 }
while (wpid != pid && wpid > 0);
4860 if (leaseFile != NULL)
4862 execve (scriptName, argv, envp);
4863 log_error (
"execve (%s, ...): %m", scriptName);
4868 for (sp = client -> env; sp; sp =
next) {
4876 gettimeofday(&
cur_tv, NULL);
4877 return (WIFEXITED (wstatus) ?
4878 WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
4882 const char *prefix,
const char *name,
const char *fmt, ...)
4890 va_start (list, fmt);
4891 len = vsnprintf (spbuf,
sizeof spbuf, fmt, list);
4894 val =
dmalloc (strlen (prefix) + strlen (name) + 1 +
4895 len +
sizeof *val,
MDL);
4897 log_error (
"client_envadd: cannot allocate space for variable");
4906 if (len >=
sizeof spbuf) {
4907 va_start (list, fmt);
4908 vsnprintf (s, len + 1, fmt, list);
4914 val ->
next = client -> env;
4915 client -> env =
val;
4938 if (j + 1 == buflen)
4948 if (j + 1 == buflen)
4963 if (write(
dfd[1], &ret, 1) != 1)
4965 (void) close(
dfd[1]);
4981 if (
dfd[0] == -1 ||
dfd[1] == -1)
4985 if (write(
dfd[1], &buf, 1) != 1)
4987 (void) close(
dfd[1]);
5002 (void) open(
"/dev/null", O_RDWR | O_CLOEXEC);
5003 (void) open(
"/dev/null", O_RDWR | O_CLOEXEC);
5004 (void) open(
"/dev/null", O_RDWR | O_CLOEXEC);
5022 pfdesc = open (
path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
5029 pf = fdopen (pfdesc,
"we");
5034 fprintf (pf,
"%ld\n", (
long)getpid ());
5045 for (client = ip -> client; client; client = client ->
next) {
5046 switch (client ->
state) {
5079 #if defined(DHCPv6) && defined(DHCP4o6)
5081 if (dhcp4o6_state < 0)
5089 client -> xid = random ();
5092 if (client -> active) {
5097 memset (&ds, 0,
sizeof ds);
5099 client -> active -> options,
5103 (
struct lease *)0, client,
5105 client -> active -> options,
5108 memcpy (client -> destination.iabuf,
5110 client -> destination.len = 4;
5117 client -> first_sending =
cur_time;
5118 client -> interval = client -> config -> initial_interval;
5129 if (client -> alias)
5145 #if defined(DHCPv6) && defined(DHCP4o6)
5164 if (!strcmp (ip ->
name, tmp ->
name)) {
5168 interface_reference (&ip, last ->
next,
MDL);
5169 interface_dereference (&last ->
next,
MDL);
5171 interface_reference (&last ->
next,
5173 interface_dereference (&ip ->
next,
5178 interface_reference (&ip,
5184 interface_dereference (&ip ->
next,
5190 tmp -> client = ip ->
client;
5191 tmp -> client ->
interface = tmp;
5193 interface_dereference (&ip,
MDL);
5228 if (ip -> client ->
alias)
5230 ip -> client ->
alias);
5242 for (client = ip->
client ; client ; client = client->
next) {
5254 struct packet *packet;
5273 static void shutdown_exit (
void *foo)
5281 #if defined (NSUPDATE)
5298 isc_result_t eresult)
5301 isc_result_t result;
5315 dhclient_ddns_cb_free(ddns_cb,
MDL);
5324 isc_result_t result;
5327 if (client->
ddns_cb != NULL) {
5333 if (ddns_cb != NULL) {
5339 ddns_cb->
cur_func = client_dns_remove_action;
5343 if (result != ISC_R_TIMEDOUT) {
5344 dhclient_ddns_cb_free(ddns_cb,
MDL);
5364 log_info(
"Received signal %d, initiating shutdown.",
5373 for (client = ip -> client; client; client = client -> next) {
5382 if (client -> active &&
5383 client -> active -> expiry >
cur_time) {
5384 #if defined (NSUPDATE)
5412 tv.tv_sec =
cur_tv.tv_sec;
5413 tv.tv_usec =
cur_tv.tv_usec + 1;
5419 #if defined (NSUPDATE)
5430 isc_result_t status = ISC_R_FAILURE;
5432 if ((client != NULL) &&
5433 ((client->
active != NULL) ||
5446 if (status != ISC_R_TIMEDOUT) {
5447 dhclient_ddns_cb_free(ddns_cb,
MDL);
5482 isc_result_t eresult)
5484 isc_result_t result;
5501 ddns_cb->
cur_func = client_dns_update_action;
5510 case ISC_R_TIMEDOUT:
5518 if (ddns_cb->
zone != NULL) {
5524 ddns_cb->
cur_func = client_dns_update_action;
5530 tv.tv_usec =
cur_tv.tv_usec;
5532 ddns_cb, NULL, NULL);
5536 dhclient_ddns_cb_free(ddns_cb,
MDL);
5554 if (!client -> sent_options)
5565 (
struct lease *)0, client,
5566 client -> sent_options,
5576 (
struct lease *)0, client,
5577 client -> sent_options,
5586 (
struct lease *)0, client,
5587 client -> sent_options,
5602 memset(&client_identifier, 0,
sizeof(client_identifier));
5626 client_identifier.data,
5627 client_identifier.len);
5645 (client_identifier.data[0] == 255)) {
5650 if (client_identifier.len <= 5)
5651 log_fatal(
"Impossible condition at %s:%d.",
5654 client_identifier.data + 5,
5655 client_identifier.len - 5);
5657 result =
get_dhcid(ddns_cb, ddns_v4_type,
5658 client_identifier.data,
5659 client_identifier.len);
5678 rcode = ISC_R_FAILURE;
5685 rcode = ISC_R_TIMEDOUT;
5708 if (client->
ddns_cb != NULL) {
5715 if (ddns_cb != NULL) {
5716 ddns_cb->
lease = (
void *)client;
5729 ddns_cb->
cur_func = client_dns_update_action;
5733 tv.tv_sec =
cur_tv.tv_sec + offset;
5734 tv.tv_usec =
cur_tv.tv_usec;
5736 ddns_cb, NULL, NULL);
5738 log_error(
"Unable to allocate dns update state for %s",
5747 struct servent *ent;
5761 ent = getservbyname(
"dhcpc",
"udp");
5763 ent = getservbyname(
"bootpc",
"udp");
5768 #ifndef __CYGWIN32__
5792 static int check_domain_name(
const char *ptr,
size_t len,
int dots)
5797 if ((len == 0) || (len > 256))
5802 for (p=ptr; (*p != 0) && (len-- > 0); p++) {
5803 if ((*p ==
'-') || (*p ==
'_')) {
5805 if (((p - ptr) == 0) || (len == 0) || (p[1] ==
'.'))
5807 }
else if (*p ==
'.') {
5811 if ((d <= 0) || (d >= 64))
5814 if ((dots > 0) && (len > 0))
5816 }
else if (isalnum((
unsigned char)*
p) == 0) {
5821 return(dots ? -1 : 0);
5824 static int check_domain_name_list(
const char *ptr,
size_t len,
int dots)
5829 if ((ptr == NULL) || (len == 0))
5832 for (p=ptr; (*p != 0) && (len > 0); p++, len--) {
5836 if (check_domain_name(ptr, p - ptr, dots) != 0)
5843 return(check_domain_name(ptr, p - ptr, dots));
5860 #ifdef ACCEPT_LIST_IN_DOMAIN_NAME
5861 return check_domain_name_list(ptr, len, 0);
5863 return check_domain_name(ptr, len, 0);
5868 return check_domain_name(ptr, len, 0);
5871 return check_domain_name_list(ptr, len, 0);
5876 for (; (*ptr != 0) && (len-- > 0); ptr++) {
5877 if(!(isalnum((
unsigned char)*ptr) ||
5878 *ptr ==
'#' || *ptr ==
'%' ||
5879 *ptr ==
'+' || *ptr ==
'-' ||
5880 *ptr ==
'_' || *ptr ==
':' ||
5881 *ptr ==
'.' || *ptr ==
',' ||
5882 *ptr ==
'@' || *ptr ==
'~' ||
5883 *ptr ==
'\\' || *ptr ==
'/' ||
5884 *ptr ==
'[' || *ptr ==
']' ||
5885 *ptr ==
'=' || *ptr ==
' '))
5900 return check_domain_name_list(ptr, len, 0);
5910 add_reject(
struct packet *packet) {
5915 log_fatal (
"no memory for reject list!");
5934 log_info(
"Server added to list of rejected servers.");
5943 if (client != NULL) {
5951 #if defined(DHCPv6) && defined(DHCP4o6)
5970 char start_msg[5] = {
'S',
'T',
'A',
'R',
'T' };
5971 char stop_msg[4] = {
'S',
'T',
'O',
'P' };
5972 char poll_msg[4] = {
'P',
'O',
'L',
'L' };
5976 if (h->type != dhcp4o6_type)
5979 cc = recv(dhcp4o6_fd, buf,
sizeof(buf), 0);
5981 return ISC_R_UNEXPECTED;
5985 (memcmp(buf, poll_msg,
sizeof(poll_msg)) == 0)) {
5987 if (dhcp4o6_state < 0)
5988 cc = send(dhcp4o6_fd, stop_msg,
5989 sizeof(stop_msg), 0);
5991 cc = send(dhcp4o6_fd, start_msg,
5992 sizeof(start_msg), 0);
5994 log_error(
"dhcpv4o6_handler: send(): %m");
5995 return ISC_R_IOERROR;
5999 return ISC_R_UNEXPECTED;
6000 memset(&raw, 0,
sizeof(raw));
6003 "no memory buffer.");
6004 return ISC_R_NOMEMORY;
6010 forw_dhcpv4_query(&raw);
6016 (memcmp(buf, stop_msg,
sizeof(stop_msg)) == 0)) {
6018 if (dhcp4o6_state > 0) {
6022 }
else if ((cc == 5) &&
6023 (memcmp(buf, start_msg,
sizeof(start_msg)) == 0)) {
6025 if (dhcp4o6_state == 0)
6031 return ISC_R_UNEXPECTED;
6032 memset(&raw, 0,
sizeof(raw));
6035 "no memory buffer.");
6036 return ISC_R_NOMEMORY;
6042 recv_dhcpv4_response(&raw);
6059 static void dhcp4o6_poll(
void *dummy) {
6060 char msg[4] = {
'P',
'O',
'L',
'L' };
6066 if (dhcp4o6_state < 0)
6071 cc = send(dhcp4o6_fd, msg,
sizeof(msg), 0);
6076 tv.tv_usec = random() % 1000000;
6088 static void dhcp4o6_resume() {
6093 for (client = ip->
client; client != NULL;
6094 client = client->
next) {
6117 char msg[5] = {
'S',
'T',
'A',
'R',
'T' };
6120 memset(&addrs, 0,
sizeof(addrs));
6122 for (client = ip->
client; client != NULL;
6123 client = client->
next) {
6129 if ((lease == NULL) || lease->
released)
6139 if ((addrs.len % 16) != 0) {
6152 if (dhcp4o6_state == 1)
6154 log_info(
"dhcp4o6_start: go to UP");
6157 cc = send(dhcp4o6_fd, msg,
sizeof(msg), 0);
6159 log_info(
"dhcp4o6_start: send(): %m");
6169 static void dhcp4o6_stop() {
6170 char msg[4] = {
'S',
'T',
'O',
'P' };
6173 if (dhcp4o6_state == -1)
6176 log_info(
"dhcp4o6_stop: go to DOWN");
6179 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 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(* dhcpv6_packet_handler)(struct interface_info *, const char *, int, int, const struct iaddr *, isc_boolean_t)
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
isc_result_t(* dhcp_interface_startup_hook)(struct interface_info *)
#define All_DHCP_Relay_Agents_and_Servers
void initialize_client_option_spaces()
void start_release6(struct client_state *client)
char * piaddrmask(struct iaddr *addr, struct iaddr *mask)
struct iaddr next_srv_addr
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)
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
struct dhc6_ia * bindings
const char * path_dhclient_duid
enum dhcp_token peek_token(const char **rval, unsigned *rlen, struct parse *cfile)
int(* dhcp_interface_shutdown_hook)(struct interface_info *)
struct data_string fwd_name
log_fatal("no memory for uname information.")
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
#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
void(* store_length)(unsigned char *, u_int32_t)
int option_state_reference(struct option_state **ptr, struct option_state *bp, const char *file, int line)
const char * print_time(TIME t)
void read_client_leases()
struct option_state * options
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)
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)
if(parse_ip_addr(cfile,&match->addr))
void(* bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)
void run_stateless(int exit_mode, u_int16_t port)
int(* dhcp_interface_discovery_hook)(struct interface_info *)
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)
isc_boolean_t no_pid_file
int addr_match(struct iaddr *, struct iaddrmatch *)
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
#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(* v6_handler)(struct packet *, struct client_state *)
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
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
char * absolute_path(const char *orgpath)
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
void(* store_tag)(unsigned char *, u_int32_t)
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)
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)
struct option * default_requested_options[NUM_DEFAULT_REQUESTED_OPTS+2+1]
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
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