aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/dhcpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/dhcpc.c')
-rw-r--r--networking/udhcp/dhcpc.c257
1 files changed, 128 insertions, 129 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index e2fb18aba..cb85fa9e3 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -49,7 +49,7 @@ struct tpacket_auxdata {
49#endif 49#endif
50 50
51 51
52/* "struct client_config_t client_config" is in bb_common_bufsiz1 */ 52/* "struct client_data_t client_data" is in bb_common_bufsiz1 */
53 53
54 54
55#if ENABLE_LONG_OPTS 55#if ENABLE_LONG_OPTS
@@ -477,7 +477,7 @@ static char **fill_envp(struct dhcp_packet *packet)
477 } 477 }
478 curr = envp = xzalloc(sizeof(envp[0]) * envc); 478 curr = envp = xzalloc(sizeof(envp[0]) * envc);
479 479
480 *curr = xasprintf("interface=%s", client_config.interface); 480 *curr = xasprintf("interface=%s", client_data.interface);
481 putenv(*curr++); 481 putenv(*curr++);
482 482
483 if (!packet) 483 if (!packet)
@@ -577,8 +577,8 @@ static void udhcp_run_script(struct dhcp_packet *packet, const char *name)
577 envp = fill_envp(packet); 577 envp = fill_envp(packet);
578 578
579 /* call script */ 579 /* call script */
580 log1("executing %s %s", client_config.script, name); 580 log1("executing %s %s", client_data.script, name);
581 argv[0] = (char*) client_config.script; 581 argv[0] = (char*) client_data.script;
582 argv[1] = (char*) name; 582 argv[1] = (char*) name;
583 argv[2] = NULL; 583 argv[2] = NULL;
584 spawn_and_wait(argv); 584 spawn_and_wait(argv);
@@ -608,15 +608,15 @@ static void init_packet(struct dhcp_packet *packet, char type)
608 608
609 packet->xid = random_xid(); 609 packet->xid = random_xid();
610 610
611 client_config.last_secs = monotonic_sec(); 611 client_data.last_secs = monotonic_sec();
612 if (client_config.first_secs == 0) 612 if (client_data.first_secs == 0)
613 client_config.first_secs = client_config.last_secs; 613 client_data.first_secs = client_data.last_secs;
614 secs = client_config.last_secs - client_config.first_secs; 614 secs = client_data.last_secs - client_data.first_secs;
615 packet->secs = htons(secs); 615 packet->secs = htons(secs);
616 616
617 memcpy(packet->chaddr, client_config.client_mac, 6); 617 memcpy(packet->chaddr, client_data.client_mac, 6);
618 if (client_config.clientid) 618 if (client_data.clientid)
619 udhcp_add_binary_option(packet, client_config.clientid); 619 udhcp_add_binary_option(packet, client_data.clientid);
620} 620}
621 621
622static void add_client_options(struct dhcp_packet *packet) 622static void add_client_options(struct dhcp_packet *packet)
@@ -631,7 +631,7 @@ static void add_client_options(struct dhcp_packet *packet)
631 end = udhcp_end_option(packet->options); 631 end = udhcp_end_option(packet->options);
632 len = 0; 632 len = 0;
633 for (i = 1; i < DHCP_END; i++) { 633 for (i = 1; i < DHCP_END; i++) {
634 if (client_config.opt_mask[i >> 3] & (1 << (i & 7))) { 634 if (client_data.opt_mask[i >> 3] & (1 << (i & 7))) {
635 packet->options[end + OPT_DATA + len] = i; 635 packet->options[end + OPT_DATA + len] = i;
636 len++; 636 len++;
637 } 637 }
@@ -642,12 +642,12 @@ static void add_client_options(struct dhcp_packet *packet)
642 packet->options[end + OPT_DATA + len] = DHCP_END; 642 packet->options[end + OPT_DATA + len] = DHCP_END;
643 } 643 }
644 644
645 if (client_config.vendorclass) 645 if (client_data.vendorclass)
646 udhcp_add_binary_option(packet, client_config.vendorclass); 646 udhcp_add_binary_option(packet, client_data.vendorclass);
647 if (client_config.hostname) 647 if (client_data.hostname)
648 udhcp_add_binary_option(packet, client_config.hostname); 648 udhcp_add_binary_option(packet, client_data.hostname);
649 if (client_config.fqdn) 649 if (client_data.fqdn)
650 udhcp_add_binary_option(packet, client_config.fqdn); 650 udhcp_add_binary_option(packet, client_data.fqdn);
651 651
652 /* Request broadcast replies if we have no IP addr */ 652 /* Request broadcast replies if we have no IP addr */
653 if ((option_mask32 & OPT_B) && packet->ciaddr == 0) 653 if ((option_mask32 & OPT_B) && packet->ciaddr == 0)
@@ -655,15 +655,15 @@ static void add_client_options(struct dhcp_packet *packet)
655 655
656 /* Add -x options if any */ 656 /* Add -x options if any */
657 { 657 {
658 struct option_set *curr = client_config.options; 658 struct option_set *curr = client_data.options;
659 while (curr) { 659 while (curr) {
660 udhcp_add_binary_option(packet, curr->data); 660 udhcp_add_binary_option(packet, curr->data);
661 curr = curr->next; 661 curr = curr->next;
662 } 662 }
663// if (client_config.sname) 663// if (client_data.sname)
664// strncpy((char*)packet->sname, client_config.sname, sizeof(packet->sname) - 1); 664// strncpy((char*)packet->sname, client_data.sname, sizeof(packet->sname) - 1);
665// if (client_config.boot_file) 665// if (client_data.boot_file)
666// strncpy((char*)packet->file, client_config.boot_file, sizeof(packet->file) - 1); 666// strncpy((char*)packet->file, client_data.boot_file, sizeof(packet->file) - 1);
667 } 667 }
668 668
669 // This will be needed if we remove -V VENDOR_STR in favor of 669 // This will be needed if we remove -V VENDOR_STR in favor of
@@ -691,12 +691,12 @@ static void add_client_options(struct dhcp_packet *packet)
691 * client reverts to using the IP broadcast address. 691 * client reverts to using the IP broadcast address.
692 */ 692 */
693 693
694static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet, uint32_t src_nip) 694static int raw_bcast_from_client_data_ifindex(struct dhcp_packet *packet, uint32_t src_nip)
695{ 695{
696 return udhcp_send_raw_packet(packet, 696 return udhcp_send_raw_packet(packet,
697 /*src*/ src_nip, CLIENT_PORT, 697 /*src*/ src_nip, CLIENT_PORT,
698 /*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR, 698 /*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR,
699 client_config.ifindex); 699 client_data.ifindex);
700} 700}
701 701
702static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server) 702static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server)
@@ -705,7 +705,7 @@ static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t
705 return udhcp_send_kernel_packet(packet, 705 return udhcp_send_kernel_packet(packet,
706 ciaddr, CLIENT_PORT, 706 ciaddr, CLIENT_PORT,
707 server, SERVER_PORT); 707 server, SERVER_PORT);
708 return raw_bcast_from_client_config_ifindex(packet, ciaddr); 708 return raw_bcast_from_client_data_ifindex(packet, ciaddr);
709} 709}
710 710
711/* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ 711/* Broadcast a DHCP discover packet to the network, with an optionally requested IP */
@@ -730,8 +730,8 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested)
730 */ 730 */
731 add_client_options(&packet); 731 add_client_options(&packet);
732 732
733 bb_error_msg("sending %s", "discover"); 733 bb_info_msg("sending %s", "discover");
734 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); 734 return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY);
735} 735}
736 736
737/* Broadcast a DHCP request message */ 737/* Broadcast a DHCP request message */
@@ -774,8 +774,8 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste
774 add_client_options(&packet); 774 add_client_options(&packet);
775 775
776 temp_addr.s_addr = requested; 776 temp_addr.s_addr = requested;
777 bb_error_msg("sending select for %s", inet_ntoa(temp_addr)); 777 bb_info_msg("sending select for %s", inet_ntoa(temp_addr));
778 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); 778 return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY);
779} 779}
780 780
781/* Unicast or broadcast a DHCP renew message */ 781/* Unicast or broadcast a DHCP renew message */
@@ -815,7 +815,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
815 add_client_options(&packet); 815 add_client_options(&packet);
816 816
817 temp_addr.s_addr = server; 817 temp_addr.s_addr = server;
818 bb_error_msg("sending renew to %s", inet_ntoa(temp_addr)); 818 bb_info_msg("sending renew to %s", inet_ntoa(temp_addr));
819 return bcast_or_ucast(&packet, ciaddr, server); 819 return bcast_or_ucast(&packet, ciaddr, server);
820} 820}
821 821
@@ -844,8 +844,8 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req
844 844
845 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); 845 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
846 846
847 bb_error_msg("sending %s", "decline"); 847 bb_info_msg("sending %s", "decline");
848 return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); 848 return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY);
849} 849}
850#endif 850#endif
851 851
@@ -866,7 +866,7 @@ int send_release(uint32_t server, uint32_t ciaddr)
866 866
867 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); 867 udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
868 868
869 bb_error_msg("sending %s", "release"); 869 bb_info_msg("sending %s", "release");
870 /* Note: normally we unicast here since "server" is not zero. 870 /* Note: normally we unicast here since "server" is not zero.
871 * However, there _are_ people who run "address-less" DHCP servers, 871 * However, there _are_ people who run "address-less" DHCP servers,
872 * and reportedly ISC dhcp client and Windows allow that. 872 * and reportedly ISC dhcp client and Windows allow that.
@@ -969,7 +969,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd)
969 skip_udp_sum_check: 969 skip_udp_sum_check:
970 970
971 if (packet.data.cookie != htonl(DHCP_MAGIC)) { 971 if (packet.data.cookie != htonl(DHCP_MAGIC)) {
972 bb_error_msg("packet with bad magic, ignoring"); 972 bb_info_msg("packet with bad magic, ignoring");
973 return -2; 973 return -2;
974 } 974 }
975 975
@@ -984,13 +984,12 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd)
984 984
985/*** Main ***/ 985/*** Main ***/
986 986
987static int sockfd = -1; 987/* Values for client_data.listen_mode */
988
989#define LISTEN_NONE 0 988#define LISTEN_NONE 0
990#define LISTEN_KERNEL 1 989#define LISTEN_KERNEL 1
991#define LISTEN_RAW 2 990#define LISTEN_RAW 2
992static smallint listen_mode;
993 991
992/* Values for client_data.state */
994/* initial state: (re)start DHCP negotiation */ 993/* initial state: (re)start DHCP negotiation */
995#define INIT_SELECTING 0 994#define INIT_SELECTING 0
996/* discover was sent, DHCPOFFER reply received */ 995/* discover was sent, DHCPOFFER reply received */
@@ -1005,7 +1004,6 @@ static smallint listen_mode;
1005#define RENEW_REQUESTED 5 1004#define RENEW_REQUESTED 5
1006/* release, possibly manually requested (SIGUSR2) */ 1005/* release, possibly manually requested (SIGUSR2) */
1007#define RELEASED 6 1006#define RELEASED 6
1008static smallint state;
1009 1007
1010static int udhcp_raw_socket(int ifindex) 1008static int udhcp_raw_socket(int ifindex)
1011{ 1009{
@@ -1102,35 +1100,35 @@ static void change_listen_mode(int new_mode)
1102 : "none" 1100 : "none"
1103 ); 1101 );
1104 1102
1105 listen_mode = new_mode; 1103 client_data.listen_mode = new_mode;
1106 if (sockfd >= 0) { 1104 if (client_data.sockfd >= 0) {
1107 close(sockfd); 1105 close(client_data.sockfd);
1108 sockfd = -1; 1106 client_data.sockfd = -1;
1109 } 1107 }
1110 if (new_mode == LISTEN_KERNEL) 1108 if (new_mode == LISTEN_KERNEL)
1111 sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT, client_config.interface); 1109 client_data.sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT, client_data.interface);
1112 else if (new_mode != LISTEN_NONE) 1110 else if (new_mode != LISTEN_NONE)
1113 sockfd = udhcp_raw_socket(client_config.ifindex); 1111 client_data.sockfd = udhcp_raw_socket(client_data.ifindex);
1114 /* else LISTEN_NONE: sockfd stays closed */ 1112 /* else LISTEN_NONE: client_data.sockfd stays closed */
1115} 1113}
1116 1114
1117/* Called only on SIGUSR1 */ 1115/* Called only on SIGUSR1 */
1118static void perform_renew(void) 1116static void perform_renew(void)
1119{ 1117{
1120 bb_error_msg("performing DHCP renew"); 1118 bb_info_msg("performing DHCP renew");
1121 switch (state) { 1119 switch (client_data.state) {
1122 case BOUND: 1120 case BOUND:
1123 change_listen_mode(LISTEN_KERNEL); 1121 change_listen_mode(LISTEN_KERNEL);
1124 case RENEWING: 1122 case RENEWING:
1125 case REBINDING: 1123 case REBINDING:
1126 state = RENEW_REQUESTED; 1124 client_data.state = RENEW_REQUESTED;
1127 break; 1125 break;
1128 case RENEW_REQUESTED: /* impatient are we? fine, square 1 */ 1126 case RENEW_REQUESTED: /* impatient are we? fine, square 1 */
1129 udhcp_run_script(NULL, "deconfig"); 1127 udhcp_run_script(NULL, "deconfig");
1130 case REQUESTING: 1128 case REQUESTING:
1131 case RELEASED: 1129 case RELEASED:
1132 change_listen_mode(LISTEN_RAW); 1130 change_listen_mode(LISTEN_RAW);
1133 state = INIT_SELECTING; 1131 client_data.state = INIT_SELECTING;
1134 break; 1132 break;
1135 case INIT_SELECTING: 1133 case INIT_SELECTING:
1136 break; 1134 break;
@@ -1143,19 +1141,19 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip)
1143 struct in_addr temp_addr; 1141 struct in_addr temp_addr;
1144 1142
1145 /* send release packet */ 1143 /* send release packet */
1146 if (state == BOUND 1144 if (client_data.state == BOUND
1147 || state == RENEWING 1145 || client_data.state == RENEWING
1148 || state == REBINDING 1146 || client_data.state == REBINDING
1149 || state == RENEW_REQUESTED 1147 || client_data.state == RENEW_REQUESTED
1150 ) { 1148 ) {
1151 temp_addr.s_addr = server_addr; 1149 temp_addr.s_addr = server_addr;
1152 strcpy(buffer, inet_ntoa(temp_addr)); 1150 strcpy(buffer, inet_ntoa(temp_addr));
1153 temp_addr.s_addr = requested_ip; 1151 temp_addr.s_addr = requested_ip;
1154 bb_error_msg("unicasting a release of %s to %s", 1152 bb_info_msg("unicasting a release of %s to %s",
1155 inet_ntoa(temp_addr), buffer); 1153 inet_ntoa(temp_addr), buffer);
1156 send_release(server_addr, requested_ip); /* unicast */ 1154 send_release(server_addr, requested_ip); /* unicast */
1157 } 1155 }
1158 bb_error_msg("entering released state"); 1156 bb_info_msg("entering released state");
1159/* 1157/*
1160 * We can be here on: SIGUSR2, 1158 * We can be here on: SIGUSR2,
1161 * or on exit (SIGTERM) and -R "release on quit" is specified. 1159 * or on exit (SIGTERM) and -R "release on quit" is specified.
@@ -1165,7 +1163,7 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip)
1165 udhcp_run_script(NULL, "deconfig"); 1163 udhcp_run_script(NULL, "deconfig");
1166 1164
1167 change_listen_mode(LISTEN_NONE); 1165 change_listen_mode(LISTEN_NONE);
1168 state = RELEASED; 1166 client_data.state = RELEASED;
1169} 1167}
1170 1168
1171static uint8_t* alloc_dhcp_option(int code, const char *str, int extra) 1169static uint8_t* alloc_dhcp_option(int code, const char *str, int extra)
@@ -1185,7 +1183,7 @@ static void client_background(void)
1185 bb_daemonize(0); 1183 bb_daemonize(0);
1186 logmode &= ~LOGMODE_STDIO; 1184 logmode &= ~LOGMODE_STDIO;
1187 /* rewrite pidfile, as our pid is different now */ 1185 /* rewrite pidfile, as our pid is different now */
1188 write_pidfile(client_config.pidfile); 1186 write_pidfile(client_data.pidfile);
1189} 1187}
1190#endif 1188#endif
1191 1189
@@ -1268,8 +1266,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1268 /* Default options */ 1266 /* Default options */
1269 IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) 1267 IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;)
1270 IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) 1268 IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;)
1271 client_config.interface = "eth0"; 1269 client_data.interface = "eth0";
1272 client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; 1270 client_data.script = CONFIG_UDHCPC_DEFAULT_SCRIPT;
1271 client_data.sockfd = -1;
1273 str_V = "udhcp "BB_VER; 1272 str_V = "udhcp "BB_VER;
1274 1273
1275 /* Parse command line */ 1274 /* Parse command line */
@@ -1283,9 +1282,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1283 "\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */ 1282 "\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */
1284 , udhcpc_longopts 1283 , udhcpc_longopts
1285 , &str_V, &str_h, &str_h, &str_F 1284 , &str_V, &str_h, &str_h, &str_F
1286 , &client_config.interface, &client_config.pidfile /* i,p */ 1285 , &client_data.interface, &client_data.pidfile /* i,p */
1287 , &str_r /* r */ 1286 , &str_r /* r */
1288 , &client_config.script /* s */ 1287 , &client_data.script /* s */
1289 , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ 1288 , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */
1290 , &list_O 1289 , &list_O
1291 , &list_x 1290 , &list_x
@@ -1296,11 +1295,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1296 if (opt & (OPT_h|OPT_H)) { 1295 if (opt & (OPT_h|OPT_H)) {
1297 //msg added 2011-11 1296 //msg added 2011-11
1298 bb_error_msg("option -h NAME is deprecated, use -x hostname:NAME"); 1297 bb_error_msg("option -h NAME is deprecated, use -x hostname:NAME");
1299 client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0); 1298 client_data.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0);
1300 } 1299 }
1301 if (opt & OPT_F) { 1300 if (opt & OPT_F) {
1302 /* FQDN option format: [0x51][len][flags][0][0]<fqdn> */ 1301 /* FQDN option format: [0x51][len][flags][0][0]<fqdn> */
1303 client_config.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3); 1302 client_data.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3);
1304 /* Flag bits: 0000NEOS 1303 /* Flag bits: 0000NEOS
1305 * S: 1 = Client requests server to update A RR in DNS as well as PTR 1304 * S: 1 = Client requests server to update A RR in DNS as well as PTR
1306 * O: 1 = Server indicates to client that DNS has been updated regardless 1305 * O: 1 = Server indicates to client that DNS has been updated regardless
@@ -1309,9 +1308,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1309 * N: 1 = Client requests server to not update DNS (S must be 0 then) 1308 * N: 1 = Client requests server to not update DNS (S must be 0 then)
1310 * Two [0] bytes which follow are deprecated and must be 0. 1309 * Two [0] bytes which follow are deprecated and must be 0.
1311 */ 1310 */
1312 client_config.fqdn[OPT_DATA + 0] = 0x1; 1311 client_data.fqdn[OPT_DATA + 0] = 0x1;
1313 /*client_config.fqdn[OPT_DATA + 1] = 0; - xzalloc did it */ 1312 /*client_data.fqdn[OPT_DATA + 1] = 0; - xzalloc did it */
1314 /*client_config.fqdn[OPT_DATA + 2] = 0; */ 1313 /*client_data.fqdn[OPT_DATA + 2] = 0; */
1315 } 1314 }
1316 if (opt & OPT_r) 1315 if (opt & OPT_r)
1317 requested_ip = inet_addr(str_r); 1316 requested_ip = inet_addr(str_r);
@@ -1329,49 +1328,49 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1329 n = udhcp_option_idx(optstr, dhcp_option_strings); 1328 n = udhcp_option_idx(optstr, dhcp_option_strings);
1330 n = dhcp_optflags[n].code; 1329 n = dhcp_optflags[n].code;
1331 } 1330 }
1332 client_config.opt_mask[n >> 3] |= 1 << (n & 7); 1331 client_data.opt_mask[n >> 3] |= 1 << (n & 7);
1333 } 1332 }
1334 if (!(opt & OPT_o)) { 1333 if (!(opt & OPT_o)) {
1335 unsigned i, n; 1334 unsigned i, n;
1336 for (i = 0; (n = dhcp_optflags[i].code) != 0; i++) { 1335 for (i = 0; (n = dhcp_optflags[i].code) != 0; i++) {
1337 if (dhcp_optflags[i].flags & OPTION_REQ) { 1336 if (dhcp_optflags[i].flags & OPTION_REQ) {
1338 client_config.opt_mask[n >> 3] |= 1 << (n & 7); 1337 client_data.opt_mask[n >> 3] |= 1 << (n & 7);
1339 } 1338 }
1340 } 1339 }
1341 } 1340 }
1342 while (list_x) { 1341 while (list_x) {
1343 char *optstr = xstrdup(llist_pop(&list_x)); 1342 char *optstr = xstrdup(llist_pop(&list_x));
1344 udhcp_str2optset(optstr, &client_config.options, 1343 udhcp_str2optset(optstr, &client_data.options,
1345 dhcp_optflags, dhcp_option_strings, 1344 dhcp_optflags, dhcp_option_strings,
1346 /*dhcpv6:*/ 0 1345 /*dhcpv6:*/ 0
1347 ); 1346 );
1348 free(optstr); 1347 free(optstr);
1349 } 1348 }
1350 1349
1351 if (udhcp_read_interface(client_config.interface, 1350 if (udhcp_read_interface(client_data.interface,
1352 &client_config.ifindex, 1351 &client_data.ifindex,
1353 NULL, 1352 NULL,
1354 client_config.client_mac) 1353 client_data.client_mac)
1355 ) { 1354 ) {
1356 return 1; 1355 return 1;
1357 } 1356 }
1358 1357
1359 clientid_mac_ptr = NULL; 1358 clientid_mac_ptr = NULL;
1360 if (!(opt & OPT_C) && !udhcp_find_option(client_config.options, DHCP_CLIENT_ID)) { 1359 if (!(opt & OPT_C) && !udhcp_find_option(client_data.options, DHCP_CLIENT_ID)) {
1361 /* not suppressed and not set, set the default client ID */ 1360 /* not suppressed and not set, set the default client ID */
1362 client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7); 1361 client_data.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7);
1363 client_config.clientid[OPT_DATA] = 1; /* type: ethernet */ 1362 client_data.clientid[OPT_DATA] = 1; /* type: ethernet */
1364 clientid_mac_ptr = client_config.clientid + OPT_DATA+1; 1363 clientid_mac_ptr = client_data.clientid + OPT_DATA+1;
1365 memcpy(clientid_mac_ptr, client_config.client_mac, 6); 1364 memcpy(clientid_mac_ptr, client_data.client_mac, 6);
1366 } 1365 }
1367 if (str_V[0] != '\0') { 1366 if (str_V[0] != '\0') {
1368 // can drop -V, str_V, client_config.vendorclass, 1367 // can drop -V, str_V, client_data.vendorclass,
1369 // but need to add "vendor" to the list of recognized 1368 // but need to add "vendor" to the list of recognized
1370 // string opts for this to work; 1369 // string opts for this to work;
1371 // and need to tweak add_client_options() too... 1370 // and need to tweak add_client_options() too...
1372 // ...so the question is, should we? 1371 // ...so the question is, should we?
1373 //bb_error_msg("option -V VENDOR is deprecated, use -x vendor:VENDOR"); 1372 //bb_error_msg("option -V VENDOR is deprecated, use -x vendor:VENDOR");
1374 client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0); 1373 client_data.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0);
1375 } 1374 }
1376 1375
1377#if !BB_MMU 1376#if !BB_MMU
@@ -1389,15 +1388,15 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1389 /* Make sure fd 0,1,2 are open */ 1388 /* Make sure fd 0,1,2 are open */
1390 bb_sanitize_stdio(); 1389 bb_sanitize_stdio();
1391 /* Create pidfile */ 1390 /* Create pidfile */
1392 write_pidfile(client_config.pidfile); 1391 write_pidfile(client_data.pidfile);
1393 /* Goes to stdout (unless NOMMU) and possibly syslog */ 1392 /* Goes to stdout (unless NOMMU) and possibly syslog */
1394 bb_error_msg("started, v"BB_VER); 1393 bb_info_msg("started, v"BB_VER);
1395 /* Set up the signal pipe */ 1394 /* Set up the signal pipe */
1396 udhcp_sp_setup(); 1395 udhcp_sp_setup();
1397 /* We want random_xid to be random... */ 1396 /* We want random_xid to be random... */
1398 srand(monotonic_us()); 1397 srand(monotonic_us());
1399 1398
1400 state = INIT_SELECTING; 1399 client_data.state = INIT_SELECTING;
1401 udhcp_run_script(NULL, "deconfig"); 1400 udhcp_run_script(NULL, "deconfig");
1402 change_listen_mode(LISTEN_RAW); 1401 change_listen_mode(LISTEN_RAW);
1403 packet_num = 0; 1402 packet_num = 0;
@@ -1415,16 +1414,16 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1415 /* silence "uninitialized!" warning */ 1414 /* silence "uninitialized!" warning */
1416 unsigned timestamp_before_wait = timestamp_before_wait; 1415 unsigned timestamp_before_wait = timestamp_before_wait;
1417 1416
1418 //bb_error_msg("sockfd:%d, listen_mode:%d", sockfd, listen_mode); 1417 //bb_error_msg("sockfd:%d, listen_mode:%d", client_data.sockfd, client_data.listen_mode);
1419 1418
1420 /* Was opening raw or udp socket here 1419 /* Was opening raw or udp socket here
1421 * if (listen_mode != LISTEN_NONE && sockfd < 0), 1420 * if (client_data.listen_mode != LISTEN_NONE && client_data.sockfd < 0),
1422 * but on fast network renew responses return faster 1421 * but on fast network renew responses return faster
1423 * than we open sockets. Thus this code is moved 1422 * than we open sockets. Thus this code is moved
1424 * to change_listen_mode(). Thus we open listen socket 1423 * to change_listen_mode(). Thus we open listen socket
1425 * BEFORE we send renew request (see "case BOUND:"). */ 1424 * BEFORE we send renew request (see "case BOUND:"). */
1426 1425
1427 udhcp_sp_fd_set(pfds, sockfd); 1426 udhcp_sp_fd_set(pfds, client_data.sockfd);
1428 1427
1429 tv = timeout - already_waited_sec; 1428 tv = timeout - already_waited_sec;
1430 retval = 0; 1429 retval = 0;
@@ -1453,20 +1452,20 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1453 * or if the status of the bridge changed). 1452 * or if the status of the bridge changed).
1454 * Refresh ifindex and client_mac: 1453 * Refresh ifindex and client_mac:
1455 */ 1454 */
1456 if (udhcp_read_interface(client_config.interface, 1455 if (udhcp_read_interface(client_data.interface,
1457 &client_config.ifindex, 1456 &client_data.ifindex,
1458 NULL, 1457 NULL,
1459 client_config.client_mac) 1458 client_data.client_mac)
1460 ) { 1459 ) {
1461 goto ret0; /* iface is gone? */ 1460 goto ret0; /* iface is gone? */
1462 } 1461 }
1463 if (clientid_mac_ptr) 1462 if (clientid_mac_ptr)
1464 memcpy(clientid_mac_ptr, client_config.client_mac, 6); 1463 memcpy(clientid_mac_ptr, client_data.client_mac, 6);
1465 1464
1466 /* We will restart the wait in any case */ 1465 /* We will restart the wait in any case */
1467 already_waited_sec = 0; 1466 already_waited_sec = 0;
1468 1467
1469 switch (state) { 1468 switch (client_data.state) {
1470 case INIT_SELECTING: 1469 case INIT_SELECTING:
1471 if (!discover_retries || packet_num < discover_retries) { 1470 if (!discover_retries || packet_num < discover_retries) {
1472 if (packet_num == 0) 1471 if (packet_num == 0)
@@ -1481,7 +1480,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1481 udhcp_run_script(NULL, "leasefail"); 1480 udhcp_run_script(NULL, "leasefail");
1482#if BB_MMU /* -b is not supported on NOMMU */ 1481#if BB_MMU /* -b is not supported on NOMMU */
1483 if (opt & OPT_b) { /* background if no lease */ 1482 if (opt & OPT_b) { /* background if no lease */
1484 bb_error_msg("no lease, forking to background"); 1483 bb_info_msg("no lease, forking to background");
1485 client_background(); 1484 client_background();
1486 /* do not background again! */ 1485 /* do not background again! */
1487 opt = ((opt & ~(OPT_b|OPT_n)) | OPT_f); 1486 opt = ((opt & ~(OPT_b|OPT_n)) | OPT_f);
@@ -1494,7 +1493,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1494 } else 1493 } else
1495#endif 1494#endif
1496 if (opt & OPT_n) { /* abort if no lease */ 1495 if (opt & OPT_n) { /* abort if no lease */
1497 bb_error_msg("no lease, failing"); 1496 bb_info_msg("no lease, failing");
1498 retval = 1; 1497 retval = 1;
1499 goto ret; 1498 goto ret;
1500 } 1499 }
@@ -1515,12 +1514,12 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1515 * were seen in the wild. Treat them similarly 1514 * were seen in the wild. Treat them similarly
1516 * to "no response to discover" case */ 1515 * to "no response to discover" case */
1517 change_listen_mode(LISTEN_RAW); 1516 change_listen_mode(LISTEN_RAW);
1518 state = INIT_SELECTING; 1517 client_data.state = INIT_SELECTING;
1519 goto leasefail; 1518 goto leasefail;
1520 case BOUND: 1519 case BOUND:
1521 /* 1/2 lease passed, enter renewing state */ 1520 /* 1/2 lease passed, enter renewing state */
1522 state = RENEWING; 1521 client_data.state = RENEWING;
1523 client_config.first_secs = 0; /* make secs field count from 0 */ 1522 client_data.first_secs = 0; /* make secs field count from 0 */
1524 change_listen_mode(LISTEN_KERNEL); 1523 change_listen_mode(LISTEN_KERNEL);
1525 log1("entering renew state"); 1524 log1("entering renew state");
1526 /* fall right through */ 1525 /* fall right through */
@@ -1556,7 +1555,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1556 } 1555 }
1557 /* Timed out or error, enter rebinding state */ 1556 /* Timed out or error, enter rebinding state */
1558 log1("entering rebinding state"); 1557 log1("entering rebinding state");
1559 state = REBINDING; 1558 client_data.state = REBINDING;
1560 /* fall right through */ 1559 /* fall right through */
1561 case REBINDING: 1560 case REBINDING:
1562 /* Switch to bcast receive */ 1561 /* Switch to bcast receive */
@@ -1570,10 +1569,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1570 continue; 1569 continue;
1571 } 1570 }
1572 /* Timed out, enter init state */ 1571 /* Timed out, enter init state */
1573 bb_error_msg("lease lost, entering init state"); 1572 bb_info_msg("lease lost, entering init state");
1574 udhcp_run_script(NULL, "deconfig"); 1573 udhcp_run_script(NULL, "deconfig");
1575 state = INIT_SELECTING; 1574 client_data.state = INIT_SELECTING;
1576 client_config.first_secs = 0; /* make secs field count from 0 */ 1575 client_data.first_secs = 0; /* make secs field count from 0 */
1577 /*timeout = 0; - already is */ 1576 /*timeout = 0; - already is */
1578 packet_num = 0; 1577 packet_num = 0;
1579 continue; 1578 continue;
@@ -1589,10 +1588,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1589 /* Is it a signal? */ 1588 /* Is it a signal? */
1590 switch (udhcp_sp_read()) { 1589 switch (udhcp_sp_read()) {
1591 case SIGUSR1: 1590 case SIGUSR1:
1592 client_config.first_secs = 0; /* make secs field count from 0 */ 1591 client_data.first_secs = 0; /* make secs field count from 0 */
1593 already_waited_sec = 0; 1592 already_waited_sec = 0;
1594 perform_renew(); 1593 perform_renew();
1595 if (state == RENEW_REQUESTED) { 1594 if (client_data.state == RENEW_REQUESTED) {
1596 /* We might be either on the same network 1595 /* We might be either on the same network
1597 * (in which case renew might work), 1596 * (in which case renew might work),
1598 * or we might be on a completely different one 1597 * or we might be on a completely different one
@@ -1615,7 +1614,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1615 timeout = INT_MAX; 1614 timeout = INT_MAX;
1616 continue; 1615 continue;
1617 case SIGTERM: 1616 case SIGTERM:
1618 bb_error_msg("received %s", "SIGTERM"); 1617 bb_info_msg("received %s", "SIGTERM");
1619 goto ret0; 1618 goto ret0;
1620 } 1619 }
1621 1620
@@ -1627,15 +1626,15 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1627 int len; 1626 int len;
1628 1627
1629 /* A packet is ready, read it */ 1628 /* A packet is ready, read it */
1630 if (listen_mode == LISTEN_KERNEL) 1629 if (client_data.listen_mode == LISTEN_KERNEL)
1631 len = udhcp_recv_kernel_packet(&packet, sockfd); 1630 len = udhcp_recv_kernel_packet(&packet, client_data.sockfd);
1632 else 1631 else
1633 len = udhcp_recv_raw_packet(&packet, sockfd); 1632 len = udhcp_recv_raw_packet(&packet, client_data.sockfd);
1634 if (len == -1) { 1633 if (len == -1) {
1635 /* Error is severe, reopen socket */ 1634 /* Error is severe, reopen socket */
1636 bb_error_msg("read error: "STRERROR_FMT", reopening socket" STRERROR_ERRNO); 1635 bb_error_msg("read error: "STRERROR_FMT", reopening socket" STRERROR_ERRNO);
1637 sleep(discover_timeout); /* 3 seconds by default */ 1636 sleep(discover_timeout); /* 3 seconds by default */
1638 change_listen_mode(listen_mode); /* just close and reopen */ 1637 change_listen_mode(client_data.listen_mode); /* just close and reopen */
1639 } 1638 }
1640 /* If this packet will turn out to be unrelated/bogus, 1639 /* If this packet will turn out to be unrelated/bogus,
1641 * we will go back and wait for next one. 1640 * we will go back and wait for next one.
@@ -1653,7 +1652,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1653 1652
1654 /* Ignore packets that aren't for us */ 1653 /* Ignore packets that aren't for us */
1655 if (packet.hlen != 6 1654 if (packet.hlen != 6
1656 || memcmp(packet.chaddr, client_config.client_mac, 6) != 0 1655 || memcmp(packet.chaddr, client_data.client_mac, 6) != 0
1657 ) { 1656 ) {
1658//FIXME: need to also check that last 10 bytes are zero 1657//FIXME: need to also check that last 10 bytes are zero
1659 log1("chaddr does not match, ignoring packet"); // log2? 1658 log1("chaddr does not match, ignoring packet"); // log2?
@@ -1662,11 +1661,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1662 1661
1663 message = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE); 1662 message = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE);
1664 if (message == NULL) { 1663 if (message == NULL) {
1665 bb_error_msg("no message type option, ignoring packet"); 1664 bb_info_msg("no message type option, ignoring packet");
1666 continue; 1665 continue;
1667 } 1666 }
1668 1667
1669 switch (state) { 1668 switch (client_data.state) {
1670 case INIT_SELECTING: 1669 case INIT_SELECTING:
1671 /* Must be a DHCPOFFER */ 1670 /* Must be a DHCPOFFER */
1672 if (*message == DHCPOFFER) { 1671 if (*message == DHCPOFFER) {
@@ -1691,7 +1690,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1691 * might work too. 1690 * might work too.
1692 * "Next server" and router are definitely wrong ones to use, though... 1691 * "Next server" and router are definitely wrong ones to use, though...
1693 */ 1692 */
1694/* We used to ignore pcakets without DHCP_SERVER_ID. 1693/* We used to ignore packets without DHCP_SERVER_ID.
1695 * I've got user reports from people who run "address-less" servers. 1694 * I've got user reports from people who run "address-less" servers.
1696 * They either supply DHCP_SERVER_ID of 0.0.0.0 or don't supply it at all. 1695 * They either supply DHCP_SERVER_ID of 0.0.0.0 or don't supply it at all.
1697 * They say ISC DHCP client supports this case. 1696 * They say ISC DHCP client supports this case.
@@ -1699,7 +1698,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1699 server_addr = 0; 1698 server_addr = 0;
1700 temp = udhcp_get_option32(&packet, DHCP_SERVER_ID); 1699 temp = udhcp_get_option32(&packet, DHCP_SERVER_ID);
1701 if (!temp) { 1700 if (!temp) {
1702 bb_error_msg("no server ID, using 0.0.0.0"); 1701 bb_info_msg("no server ID, using 0.0.0.0");
1703 } else { 1702 } else {
1704 /* it IS unaligned sometimes, don't "optimize" */ 1703 /* it IS unaligned sometimes, don't "optimize" */
1705 move_from_unaligned32(server_addr, temp); 1704 move_from_unaligned32(server_addr, temp);
@@ -1708,7 +1707,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1708 requested_ip = packet.yiaddr; 1707 requested_ip = packet.yiaddr;
1709 1708
1710 /* enter requesting state */ 1709 /* enter requesting state */
1711 state = REQUESTING; 1710 client_data.state = REQUESTING;
1712 timeout = 0; 1711 timeout = 0;
1713 packet_num = 0; 1712 packet_num = 0;
1714 already_waited_sec = 0; 1713 already_waited_sec = 0;
@@ -1726,7 +1725,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1726 1725
1727 temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME); 1726 temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME);
1728 if (!temp) { 1727 if (!temp) {
1729 bb_error_msg("no lease time with ACK, using 1 hour lease"); 1728 bb_info_msg("no lease time with ACK, using 1 hour lease");
1730 lease_seconds = 60 * 60; 1729 lease_seconds = 60 * 60;
1731 } else { 1730 } else {
1732 /* it IS unaligned sometimes, don't "optimize" */ 1731 /* it IS unaligned sometimes, don't "optimize" */
@@ -1755,19 +1754,19 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1755 if (!arpping(packet.yiaddr, 1754 if (!arpping(packet.yiaddr,
1756 NULL, 1755 NULL,
1757 (uint32_t) 0, 1756 (uint32_t) 0,
1758 client_config.client_mac, 1757 client_data.client_mac,
1759 client_config.interface, 1758 client_data.interface,
1760 arpping_ms) 1759 arpping_ms)
1761 ) { 1760 ) {
1762 bb_error_msg("offered address is in use " 1761 bb_info_msg("offered address is in use "
1763 "(got ARP reply), declining"); 1762 "(got ARP reply), declining");
1764 send_decline(/*xid,*/ server_addr, packet.yiaddr); 1763 send_decline(/*xid,*/ server_addr, packet.yiaddr);
1765 1764
1766 if (state != REQUESTING) 1765 if (client_data.state != REQUESTING)
1767 udhcp_run_script(NULL, "deconfig"); 1766 udhcp_run_script(NULL, "deconfig");
1768 change_listen_mode(LISTEN_RAW); 1767 change_listen_mode(LISTEN_RAW);
1769 state = INIT_SELECTING; 1768 client_data.state = INIT_SELECTING;
1770 client_config.first_secs = 0; /* make secs field count from 0 */ 1769 client_data.first_secs = 0; /* make secs field count from 0 */
1771 requested_ip = 0; 1770 requested_ip = 0;
1772 timeout = tryagain_timeout; 1771 timeout = tryagain_timeout;
1773 packet_num = 0; 1772 packet_num = 0;
@@ -1778,12 +1777,12 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1778#endif 1777#endif
1779 /* enter bound state */ 1778 /* enter bound state */
1780 temp_addr.s_addr = packet.yiaddr; 1779 temp_addr.s_addr = packet.yiaddr;
1781 bb_error_msg("lease of %s obtained, lease time %u", 1780 bb_info_msg("lease of %s obtained, lease time %u",
1782 inet_ntoa(temp_addr), (unsigned)lease_seconds); 1781 inet_ntoa(temp_addr), (unsigned)lease_seconds);
1783 requested_ip = packet.yiaddr; 1782 requested_ip = packet.yiaddr;
1784 1783
1785 start = monotonic_sec(); 1784 start = monotonic_sec();
1786 udhcp_run_script(&packet, state == REQUESTING ? "bound" : "renew"); 1785 udhcp_run_script(&packet, client_data.state == REQUESTING ? "bound" : "renew");
1787 already_waited_sec = (unsigned)monotonic_sec() - start; 1786 already_waited_sec = (unsigned)monotonic_sec() - start;
1788 timeout = lease_seconds / 2; 1787 timeout = lease_seconds / 2;
1789 if ((unsigned)timeout < already_waited_sec) { 1788 if ((unsigned)timeout < already_waited_sec) {
@@ -1791,7 +1790,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1791 timeout = already_waited_sec = 0; 1790 timeout = already_waited_sec = 0;
1792 } 1791 }
1793 1792
1794 state = BOUND; 1793 client_data.state = BOUND;
1795 change_listen_mode(LISTEN_NONE); 1794 change_listen_mode(LISTEN_NONE);
1796 if (opt & OPT_q) { /* quit after lease */ 1795 if (opt & OPT_q) { /* quit after lease */
1797 goto ret0; 1796 goto ret0;
@@ -1831,14 +1830,14 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1831 goto non_matching_svid; 1830 goto non_matching_svid;
1832 } 1831 }
1833 /* return to init state */ 1832 /* return to init state */
1834 bb_error_msg("received %s", "DHCP NAK"); 1833 bb_info_msg("received %s", "DHCP NAK");
1835 udhcp_run_script(&packet, "nak"); 1834 udhcp_run_script(&packet, "nak");
1836 if (state != REQUESTING) 1835 if (client_data.state != REQUESTING)
1837 udhcp_run_script(NULL, "deconfig"); 1836 udhcp_run_script(NULL, "deconfig");
1838 change_listen_mode(LISTEN_RAW); 1837 change_listen_mode(LISTEN_RAW);
1839 sleep(3); /* avoid excessive network traffic */ 1838 sleep(3); /* avoid excessive network traffic */
1840 state = INIT_SELECTING; 1839 client_data.state = INIT_SELECTING;
1841 client_config.first_secs = 0; /* make secs field count from 0 */ 1840 client_data.first_secs = 0; /* make secs field count from 0 */
1842 requested_ip = 0; 1841 requested_ip = 0;
1843 timeout = 0; 1842 timeout = 0;
1844 packet_num = 0; 1843 packet_num = 0;
@@ -1856,7 +1855,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1856 perform_release(server_addr, requested_ip); 1855 perform_release(server_addr, requested_ip);
1857 retval = 0; 1856 retval = 0;
1858 ret: 1857 ret:
1859 /*if (client_config.pidfile) - remove_pidfile has its own check */ 1858 /*if (client_data.pidfile) - remove_pidfile has its own check */
1860 remove_pidfile(client_config.pidfile); 1859 remove_pidfile(client_data.pidfile);
1861 return retval; 1860 return retval;
1862} 1861}