aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/d6_dhcpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/d6_dhcpc.c')
-rw-r--r--networking/udhcp/d6_dhcpc.c201
1 files changed, 100 insertions, 101 deletions
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index 3562988fd..15e9f3924 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -63,7 +63,7 @@
63#include <netpacket/packet.h> 63#include <netpacket/packet.h>
64#include <linux/filter.h> 64#include <linux/filter.h>
65 65
66/* "struct client_config_t client_config" is in bb_common_bufsiz1 */ 66/* "struct client_data_t client_data" is in bb_common_bufsiz1 */
67 67
68static const struct dhcp_optflag d6_optflags[] = { 68static const struct dhcp_optflag d6_optflags[] = {
69#if ENABLE_FEATURE_UDHCPC6_RFC3646 69#if ENABLE_FEATURE_UDHCPC6_RFC3646
@@ -427,7 +427,7 @@ static char **fill_envp(const uint8_t *option, const uint8_t *option_end)
427 client6_data.env_ptr = NULL; 427 client6_data.env_ptr = NULL;
428 client6_data.env_idx = 0; 428 client6_data.env_idx = 0;
429 429
430 *new_env() = xasprintf("interface=%s", client_config.interface); 430 *new_env() = xasprintf("interface=%s", client_data.interface);
431 431
432 if (option) 432 if (option)
433 option_to_env(option, option_end); 433 option_to_env(option, option_end);
@@ -449,8 +449,8 @@ static void d6_run_script(const uint8_t *option, const uint8_t *option_end,
449 envp = fill_envp(option, option_end); 449 envp = fill_envp(option, option_end);
450 450
451 /* call script */ 451 /* call script */
452 log1("executing %s %s", client_config.script, name); 452 log1("executing %s %s", client_data.script, name);
453 argv[0] = (char*) client_config.script; 453 argv[0] = (char*) client_data.script;
454 argv[1] = (char*) name; 454 argv[1] = (char*) name;
455 argv[2] = NULL; 455 argv[2] = NULL;
456 spawn_and_wait(argv); 456 spawn_and_wait(argv);
@@ -486,7 +486,7 @@ static uint8_t *init_d6_packet(struct d6_packet *packet, char type, uint32_t xid
486 packet->d6_xid32 = xid; 486 packet->d6_xid32 = xid;
487 packet->d6_msg_type = type; 487 packet->d6_msg_type = type;
488 488
489 clientid = (void*)client_config.clientid; 489 clientid = (void*)client_data.clientid;
490 return mempcpy(packet->d6_options, clientid, clientid->len + 2+2); 490 return mempcpy(packet->d6_options, clientid, clientid->len + 2+2);
491} 491}
492 492
@@ -499,7 +499,7 @@ static uint8_t *add_d6_client_options(uint8_t *ptr)
499 499
500 ptr += 4; 500 ptr += 4;
501 for (option = 1; option < 256; option++) { 501 for (option = 1; option < 256; option++) {
502 if (client_config.opt_mask[option >> 3] & (1 << (option & 7))) { 502 if (client_data.opt_mask[option >> 3] & (1 << (option & 7))) {
503 ptr[0] = (option >> 8); 503 ptr[0] = (option >> 8);
504 ptr[1] = option; 504 ptr[1] = option;
505 ptr += 2; 505 ptr += 2;
@@ -518,7 +518,7 @@ static uint8_t *add_d6_client_options(uint8_t *ptr)
518 ptr = mempcpy(ptr, &opt_fqdn_req, sizeof(opt_fqdn_req)); 518 ptr = mempcpy(ptr, &opt_fqdn_req, sizeof(opt_fqdn_req));
519#endif 519#endif
520 /* Add -x options if any */ 520 /* Add -x options if any */
521 curr = client_config.options; 521 curr = client_data.options;
522 while (curr) { 522 while (curr) {
523 len = (curr->data[D6_OPT_LEN] << 8) | curr->data[D6_OPT_LEN + 1]; 523 len = (curr->data[D6_OPT_LEN] << 8) | curr->data[D6_OPT_LEN + 1];
524 ptr = mempcpy(ptr, curr->data, D6_OPT_DATA + len); 524 ptr = mempcpy(ptr, curr->data, D6_OPT_DATA + len);
@@ -528,7 +528,7 @@ static uint8_t *add_d6_client_options(uint8_t *ptr)
528 return ptr; 528 return ptr;
529} 529}
530 530
531static int d6_mcast_from_client_config_ifindex(struct d6_packet *packet, uint8_t *end) 531static int d6_mcast_from_client_data_ifindex(struct d6_packet *packet, uint8_t *end)
532{ 532{
533 /* FF02::1:2 is "All_DHCP_Relay_Agents_and_Servers" address */ 533 /* FF02::1:2 is "All_DHCP_Relay_Agents_and_Servers" address */
534 static const uint8_t FF02__1_2[16] = { 534 static const uint8_t FF02__1_2[16] = {
@@ -540,7 +540,7 @@ static int d6_mcast_from_client_config_ifindex(struct d6_packet *packet, uint8_t
540 packet, (end - (uint8_t*) packet), 540 packet, (end - (uint8_t*) packet),
541 /*src*/ &client6_data.ll_ip6, CLIENT_PORT6, 541 /*src*/ &client6_data.ll_ip6, CLIENT_PORT6,
542 /*dst*/ (struct in6_addr*)FF02__1_2, SERVER_PORT6, MAC_BCAST_ADDR, 542 /*dst*/ (struct in6_addr*)FF02__1_2, SERVER_PORT6, MAC_BCAST_ADDR,
543 client_config.ifindex 543 client_data.ifindex
544 ); 544 );
545} 545}
546 546
@@ -670,8 +670,8 @@ static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ip
670 */ 670 */
671 opt_ptr = add_d6_client_options(opt_ptr); 671 opt_ptr = add_d6_client_options(opt_ptr);
672 672
673 bb_error_msg("sending %s", "discover"); 673 bb_info_msg("sending %s", "discover");
674 return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); 674 return d6_mcast_from_client_data_ifindex(&packet, opt_ptr);
675} 675}
676 676
677/* Multicast a DHCPv6 request message 677/* Multicast a DHCPv6 request message
@@ -727,8 +727,8 @@ static NOINLINE int send_d6_select(uint32_t xid)
727 */ 727 */
728 opt_ptr = add_d6_client_options(opt_ptr); 728 opt_ptr = add_d6_client_options(opt_ptr);
729 729
730 bb_error_msg("sending %s", "select"); 730 bb_info_msg("sending %s", "select");
731 return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); 731 return d6_mcast_from_client_data_ifindex(&packet, opt_ptr);
732} 732}
733 733
734/* Unicast or broadcast a DHCP renew message 734/* Unicast or broadcast a DHCP renew message
@@ -800,15 +800,15 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st
800 */ 800 */
801 opt_ptr = add_d6_client_options(opt_ptr); 801 opt_ptr = add_d6_client_options(opt_ptr);
802 802
803 bb_error_msg("sending %s", "renew"); 803 bb_info_msg("sending %s", "renew");
804 if (server_ipv6) 804 if (server_ipv6)
805 return d6_send_kernel_packet( 805 return d6_send_kernel_packet(
806 &packet, (opt_ptr - (uint8_t*) &packet), 806 &packet, (opt_ptr - (uint8_t*) &packet),
807 our_cur_ipv6, CLIENT_PORT6, 807 our_cur_ipv6, CLIENT_PORT6,
808 server_ipv6, SERVER_PORT6, 808 server_ipv6, SERVER_PORT6,
809 client_config.ifindex 809 client_data.ifindex
810 ); 810 );
811 return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); 811 return d6_mcast_from_client_data_ifindex(&packet, opt_ptr);
812} 812}
813 813
814/* Unicast a DHCP release message */ 814/* Unicast a DHCP release message */
@@ -830,12 +830,12 @@ int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6)
830 if (client6_data.ia_pd) 830 if (client6_data.ia_pd)
831 opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, client6_data.ia_pd->len + 2+2); 831 opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, client6_data.ia_pd->len + 2+2);
832 832
833 bb_error_msg("sending %s", "release"); 833 bb_info_msg("sending %s", "release");
834 return d6_send_kernel_packet( 834 return d6_send_kernel_packet(
835 &packet, (opt_ptr - (uint8_t*) &packet), 835 &packet, (opt_ptr - (uint8_t*) &packet),
836 our_cur_ipv6, CLIENT_PORT6, 836 our_cur_ipv6, CLIENT_PORT6,
837 server_ipv6, SERVER_PORT6, 837 server_ipv6, SERVER_PORT6,
838 client_config.ifindex 838 client_data.ifindex
839 ); 839 );
840} 840}
841 841
@@ -903,13 +903,12 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6, struct d6_pac
903 903
904/*** Main ***/ 904/*** Main ***/
905 905
906static int sockfd = -1; 906/* Values for client_data.listen_mode */
907
908#define LISTEN_NONE 0 907#define LISTEN_NONE 0
909#define LISTEN_KERNEL 1 908#define LISTEN_KERNEL 1
910#define LISTEN_RAW 2 909#define LISTEN_RAW 2
911static smallint listen_mode;
912 910
911/* Values for client_data.state */
913/* initial state: (re)start DHCP negotiation */ 912/* initial state: (re)start DHCP negotiation */
914#define INIT_SELECTING 0 913#define INIT_SELECTING 0
915/* discover was sent, DHCPOFFER reply received */ 914/* discover was sent, DHCPOFFER reply received */
@@ -924,7 +923,6 @@ static smallint listen_mode;
924#define RENEW_REQUESTED 5 923#define RENEW_REQUESTED 5
925/* release, possibly manually requested (SIGUSR2) */ 924/* release, possibly manually requested (SIGUSR2) */
926#define RELEASED 6 925#define RELEASED 6
927static smallint state;
928 926
929static int d6_raw_socket(int ifindex) 927static int d6_raw_socket(int ifindex)
930{ 928{
@@ -1018,35 +1016,35 @@ static void change_listen_mode(int new_mode)
1018 : "none" 1016 : "none"
1019 ); 1017 );
1020 1018
1021 listen_mode = new_mode; 1019 client_data.listen_mode = new_mode;
1022 if (sockfd >= 0) { 1020 if (client_data.sockfd >= 0) {
1023 close(sockfd); 1021 close(client_data.sockfd);
1024 sockfd = -1; 1022 client_data.sockfd = -1;
1025 } 1023 }
1026 if (new_mode == LISTEN_KERNEL) 1024 if (new_mode == LISTEN_KERNEL)
1027 sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT6, client_config.interface); 1025 client_data.sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT6, client_data.interface);
1028 else if (new_mode != LISTEN_NONE) 1026 else if (new_mode != LISTEN_NONE)
1029 sockfd = d6_raw_socket(client_config.ifindex); 1027 client_data.sockfd = d6_raw_socket(client_data.ifindex);
1030 /* else LISTEN_NONE: sockfd stays closed */ 1028 /* else LISTEN_NONE: client_data.sockfd stays closed */
1031} 1029}
1032 1030
1033/* Called only on SIGUSR1 */ 1031/* Called only on SIGUSR1 */
1034static void perform_renew(void) 1032static void perform_renew(void)
1035{ 1033{
1036 bb_error_msg("performing DHCP renew"); 1034 bb_info_msg("performing DHCP renew");
1037 switch (state) { 1035 switch (client_data.state) {
1038 case BOUND: 1036 case BOUND:
1039 change_listen_mode(LISTEN_KERNEL); 1037 change_listen_mode(LISTEN_KERNEL);
1040 case RENEWING: 1038 case RENEWING:
1041 case REBINDING: 1039 case REBINDING:
1042 state = RENEW_REQUESTED; 1040 client_data.state = RENEW_REQUESTED;
1043 break; 1041 break;
1044 case RENEW_REQUESTED: /* impatient are we? fine, square 1 */ 1042 case RENEW_REQUESTED: /* impatient are we? fine, square 1 */
1045 d6_run_script_no_option("deconfig"); 1043 d6_run_script_no_option("deconfig");
1046 case REQUESTING: 1044 case REQUESTING:
1047 case RELEASED: 1045 case RELEASED:
1048 change_listen_mode(LISTEN_RAW); 1046 change_listen_mode(LISTEN_RAW);
1049 state = INIT_SELECTING; 1047 client_data.state = INIT_SELECTING;
1050 break; 1048 break;
1051 case INIT_SELECTING: 1049 case INIT_SELECTING:
1052 break; 1050 break;
@@ -1056,15 +1054,15 @@ static void perform_renew(void)
1056static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) 1054static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6)
1057{ 1055{
1058 /* send release packet */ 1056 /* send release packet */
1059 if (state == BOUND 1057 if (client_data.state == BOUND
1060 || state == RENEWING 1058 || client_data.state == RENEWING
1061 || state == REBINDING 1059 || client_data.state == REBINDING
1062 || state == RENEW_REQUESTED 1060 || client_data.state == RENEW_REQUESTED
1063 ) { 1061 ) {
1064 bb_error_msg("unicasting a release"); 1062 bb_info_msg("unicasting a release");
1065 send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ 1063 send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */
1066 } 1064 }
1067 bb_error_msg("entering released state"); 1065 bb_info_msg("entering released state");
1068/* 1066/*
1069 * We can be here on: SIGUSR2, 1067 * We can be here on: SIGUSR2,
1070 * or on exit (SIGTERM) and -R "release on quit" is specified. 1068 * or on exit (SIGTERM) and -R "release on quit" is specified.
@@ -1073,7 +1071,7 @@ static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *ou
1073 */ 1071 */
1074 d6_run_script_no_option("deconfig"); 1072 d6_run_script_no_option("deconfig");
1075 change_listen_mode(LISTEN_NONE); 1073 change_listen_mode(LISTEN_NONE);
1076 state = RELEASED; 1074 client_data.state = RELEASED;
1077} 1075}
1078 1076
1079///static uint8_t* alloc_dhcp_option(int code, const char *str, int extra) 1077///static uint8_t* alloc_dhcp_option(int code, const char *str, int extra)
@@ -1093,7 +1091,7 @@ static void client_background(void)
1093 bb_daemonize(0); 1091 bb_daemonize(0);
1094 logmode &= ~LOGMODE_STDIO; 1092 logmode &= ~LOGMODE_STDIO;
1095 /* rewrite pidfile, as our pid is different now */ 1093 /* rewrite pidfile, as our pid is different now */
1096 write_pidfile(client_config.pidfile); 1094 write_pidfile(client_data.pidfile);
1097} 1095}
1098#endif 1096#endif
1099 1097
@@ -1172,8 +1170,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1172 /* Default options */ 1170 /* Default options */
1173 IF_FEATURE_UDHCP_PORT(SERVER_PORT6 = 547;) 1171 IF_FEATURE_UDHCP_PORT(SERVER_PORT6 = 547;)
1174 IF_FEATURE_UDHCP_PORT(CLIENT_PORT6 = 546;) 1172 IF_FEATURE_UDHCP_PORT(CLIENT_PORT6 = 546;)
1175 client_config.interface = "eth0"; 1173 client_data.interface = "eth0";
1176 client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; 1174 client_data.script = CONFIG_UDHCPC_DEFAULT_SCRIPT;
1175 client_data.sockfd = -1;
1177 1176
1178 /* Parse command line */ 1177 /* Parse command line */
1179 opt = getopt32long(argv, "^" 1178 opt = getopt32long(argv, "^"
@@ -1185,8 +1184,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1185 "v" 1184 "v"
1186 "\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */ 1185 "\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */
1187 , udhcpc6_longopts 1186 , udhcpc6_longopts
1188 , &client_config.interface, &client_config.pidfile, &str_r /* i,p */ 1187 , &client_data.interface, &client_data.pidfile, &str_r /* i,p */
1189 , &client_config.script /* s */ 1188 , &client_data.script /* s */
1190 , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ 1189 , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */
1191 , &list_O 1190 , &list_O
1192 , &list_x 1191 , &list_x
@@ -1217,29 +1216,29 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1217 n = udhcp_option_idx(optstr, d6_option_strings); 1216 n = udhcp_option_idx(optstr, d6_option_strings);
1218 n = d6_optflags[n].code; 1217 n = d6_optflags[n].code;
1219 } 1218 }
1220 client_config.opt_mask[n >> 3] |= 1 << (n & 7); 1219 client_data.opt_mask[n >> 3] |= 1 << (n & 7);
1221 } 1220 }
1222 if (!(opt & OPT_o)) { 1221 if (!(opt & OPT_o)) {
1223 unsigned i, n; 1222 unsigned i, n;
1224 for (i = 0; (n = d6_optflags[i].code) != 0; i++) { 1223 for (i = 0; (n = d6_optflags[i].code) != 0; i++) {
1225 if (d6_optflags[i].flags & OPTION_REQ) { 1224 if (d6_optflags[i].flags & OPTION_REQ) {
1226 client_config.opt_mask[n >> 3] |= 1 << (n & 7); 1225 client_data.opt_mask[n >> 3] |= 1 << (n & 7);
1227 } 1226 }
1228 } 1227 }
1229 } 1228 }
1230 while (list_x) { 1229 while (list_x) {
1231 char *optstr = xstrdup(llist_pop(&list_x)); 1230 char *optstr = xstrdup(llist_pop(&list_x));
1232 udhcp_str2optset(optstr, &client_config.options, 1231 udhcp_str2optset(optstr, &client_data.options,
1233 d6_optflags, d6_option_strings, 1232 d6_optflags, d6_option_strings,
1234 /*dhcpv6:*/ 1 1233 /*dhcpv6:*/ 1
1235 ); 1234 );
1236 free(optstr); 1235 free(optstr);
1237 } 1236 }
1238 1237
1239 if (d6_read_interface(client_config.interface, 1238 if (d6_read_interface(client_data.interface,
1240 &client_config.ifindex, 1239 &client_data.ifindex,
1241 &client6_data.ll_ip6, 1240 &client6_data.ll_ip6,
1242 client_config.client_mac) 1241 client_data.client_mac)
1243 ) { 1242 ) {
1244 return 1; 1243 return 1;
1245 } 1244 }
@@ -1253,8 +1252,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1253 clientid->data[1] = 3; /* DUID-LL */ 1252 clientid->data[1] = 3; /* DUID-LL */
1254 clientid->data[3] = 1; /* ethernet */ 1253 clientid->data[3] = 1; /* ethernet */
1255 clientid_mac_ptr = clientid->data + 2+2; 1254 clientid_mac_ptr = clientid->data + 2+2;
1256 memcpy(clientid_mac_ptr, client_config.client_mac, 6); 1255 memcpy(clientid_mac_ptr, client_data.client_mac, 6);
1257 client_config.clientid = (void*)clientid; 1256 client_data.clientid = (void*)clientid;
1258 } 1257 }
1259 1258
1260#if !BB_MMU 1259#if !BB_MMU
@@ -1272,13 +1271,13 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1272 /* Make sure fd 0,1,2 are open */ 1271 /* Make sure fd 0,1,2 are open */
1273 bb_sanitize_stdio(); 1272 bb_sanitize_stdio();
1274 /* Create pidfile */ 1273 /* Create pidfile */
1275 write_pidfile(client_config.pidfile); 1274 write_pidfile(client_data.pidfile);
1276 /* Goes to stdout (unless NOMMU) and possibly syslog */ 1275 /* Goes to stdout (unless NOMMU) and possibly syslog */
1277 bb_error_msg("started, v"BB_VER); 1276 bb_info_msg("started, v"BB_VER);
1278 /* Set up the signal pipe */ 1277 /* Set up the signal pipe */
1279 udhcp_sp_setup(); 1278 udhcp_sp_setup();
1280 1279
1281 state = INIT_SELECTING; 1280 client_data.state = INIT_SELECTING;
1282 d6_run_script_no_option("deconfig"); 1281 d6_run_script_no_option("deconfig");
1283 change_listen_mode(LISTEN_RAW); 1282 change_listen_mode(LISTEN_RAW);
1284 packet_num = 0; 1283 packet_num = 0;
@@ -1297,16 +1296,16 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1297 /* silence "uninitialized!" warning */ 1296 /* silence "uninitialized!" warning */
1298 unsigned timestamp_before_wait = timestamp_before_wait; 1297 unsigned timestamp_before_wait = timestamp_before_wait;
1299 1298
1300 //bb_error_msg("sockfd:%d, listen_mode:%d", sockfd, listen_mode); 1299 //bb_error_msg("sockfd:%d, listen_mode:%d", client_data.sockfd, client_data.listen_mode);
1301 1300
1302 /* Was opening raw or udp socket here 1301 /* Was opening raw or udp socket here
1303 * if (listen_mode != LISTEN_NONE && sockfd < 0), 1302 * if (client_data.listen_mode != LISTEN_NONE && client_data.sockfd < 0),
1304 * but on fast network renew responses return faster 1303 * but on fast network renew responses return faster
1305 * than we open sockets. Thus this code is moved 1304 * than we open sockets. Thus this code is moved
1306 * to change_listen_mode(). Thus we open listen socket 1305 * to change_listen_mode(). Thus we open listen socket
1307 * BEFORE we send renew request (see "case BOUND:"). */ 1306 * BEFORE we send renew request (see "case BOUND:"). */
1308 1307
1309 udhcp_sp_fd_set(pfds, sockfd); 1308 udhcp_sp_fd_set(pfds, client_data.sockfd);
1310 1309
1311 tv = timeout - already_waited_sec; 1310 tv = timeout - already_waited_sec;
1312 retval = 0; 1311 retval = 0;
@@ -1335,20 +1334,20 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1335 * or if the status of the bridge changed). 1334 * or if the status of the bridge changed).
1336 * Refresh ifindex and client_mac: 1335 * Refresh ifindex and client_mac:
1337 */ 1336 */
1338 if (d6_read_interface(client_config.interface, 1337 if (d6_read_interface(client_data.interface,
1339 &client_config.ifindex, 1338 &client_data.ifindex,
1340 &client6_data.ll_ip6, 1339 &client6_data.ll_ip6,
1341 client_config.client_mac) 1340 client_data.client_mac)
1342 ) { 1341 ) {
1343 goto ret0; /* iface is gone? */ 1342 goto ret0; /* iface is gone? */
1344 } 1343 }
1345 1344
1346 memcpy(clientid_mac_ptr, client_config.client_mac, 6); 1345 memcpy(clientid_mac_ptr, client_data.client_mac, 6);
1347 1346
1348 /* We will restart the wait in any case */ 1347 /* We will restart the wait in any case */
1349 already_waited_sec = 0; 1348 already_waited_sec = 0;
1350 1349
1351 switch (state) { 1350 switch (client_data.state) {
1352 case INIT_SELECTING: 1351 case INIT_SELECTING:
1353 if (!discover_retries || packet_num < discover_retries) { 1352 if (!discover_retries || packet_num < discover_retries) {
1354 if (packet_num == 0) 1353 if (packet_num == 0)
@@ -1363,7 +1362,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1363 d6_run_script_no_option("leasefail"); 1362 d6_run_script_no_option("leasefail");
1364#if BB_MMU /* -b is not supported on NOMMU */ 1363#if BB_MMU /* -b is not supported on NOMMU */
1365 if (opt & OPT_b) { /* background if no lease */ 1364 if (opt & OPT_b) { /* background if no lease */
1366 bb_error_msg("no lease, forking to background"); 1365 bb_info_msg("no lease, forking to background");
1367 client_background(); 1366 client_background();
1368 /* do not background again! */ 1367 /* do not background again! */
1369 opt = ((opt & ~(OPT_b|OPT_n)) | OPT_f); 1368 opt = ((opt & ~(OPT_b|OPT_n)) | OPT_f);
@@ -1376,7 +1375,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1376 } else 1375 } else
1377#endif 1376#endif
1378 if (opt & OPT_n) { /* abort if no lease */ 1377 if (opt & OPT_n) { /* abort if no lease */
1379 bb_error_msg("no lease, failing"); 1378 bb_info_msg("no lease, failing");
1380 retval = 1; 1379 retval = 1;
1381 goto ret; 1380 goto ret;
1382 } 1381 }
@@ -1397,12 +1396,12 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1397 * were seen in the wild. Treat them similarly 1396 * were seen in the wild. Treat them similarly
1398 * to "no response to discover" case */ 1397 * to "no response to discover" case */
1399 change_listen_mode(LISTEN_RAW); 1398 change_listen_mode(LISTEN_RAW);
1400 state = INIT_SELECTING; 1399 client_data.state = INIT_SELECTING;
1401 goto leasefail; 1400 goto leasefail;
1402 case BOUND: 1401 case BOUND:
1403 /* 1/2 lease passed, enter renewing state */ 1402 /* 1/2 lease passed, enter renewing state */
1404 state = RENEWING; 1403 client_data.state = RENEWING;
1405 client_config.first_secs = 0; /* make secs field count from 0 */ 1404 client_data.first_secs = 0; /* make secs field count from 0 */
1406 change_listen_mode(LISTEN_KERNEL); 1405 change_listen_mode(LISTEN_KERNEL);
1407 log1("entering renew state"); 1406 log1("entering renew state");
1408 /* fall right through */ 1407 /* fall right through */
@@ -1425,7 +1424,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1425 } 1424 }
1426 /* Timed out, enter rebinding state */ 1425 /* Timed out, enter rebinding state */
1427 log1("entering rebinding state"); 1426 log1("entering rebinding state");
1428 state = REBINDING; 1427 client_data.state = REBINDING;
1429 /* fall right through */ 1428 /* fall right through */
1430 case REBINDING: 1429 case REBINDING:
1431 /* Switch to bcast receive */ 1430 /* Switch to bcast receive */
@@ -1439,10 +1438,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1439 continue; 1438 continue;
1440 } 1439 }
1441 /* Timed out, enter init state */ 1440 /* Timed out, enter init state */
1442 bb_error_msg("lease lost, entering init state"); 1441 bb_info_msg("lease lost, entering init state");
1443 d6_run_script_no_option("deconfig"); 1442 d6_run_script_no_option("deconfig");
1444 state = INIT_SELECTING; 1443 client_data.state = INIT_SELECTING;
1445 client_config.first_secs = 0; /* make secs field count from 0 */ 1444 client_data.first_secs = 0; /* make secs field count from 0 */
1446 /*timeout = 0; - already is */ 1445 /*timeout = 0; - already is */
1447 packet_num = 0; 1446 packet_num = 0;
1448 continue; 1447 continue;
@@ -1458,10 +1457,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1458 /* Is it a signal? */ 1457 /* Is it a signal? */
1459 switch (udhcp_sp_read()) { 1458 switch (udhcp_sp_read()) {
1460 case SIGUSR1: 1459 case SIGUSR1:
1461 client_config.first_secs = 0; /* make secs field count from 0 */ 1460 client_data.first_secs = 0; /* make secs field count from 0 */
1462 already_waited_sec = 0; 1461 already_waited_sec = 0;
1463 perform_renew(); 1462 perform_renew();
1464 if (state == RENEW_REQUESTED) { 1463 if (client_data.state == RENEW_REQUESTED) {
1465 /* We might be either on the same network 1464 /* We might be either on the same network
1466 * (in which case renew might work), 1465 * (in which case renew might work),
1467 * or we might be on a completely different one 1466 * or we might be on a completely different one
@@ -1484,7 +1483,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1484 timeout = INT_MAX; 1483 timeout = INT_MAX;
1485 continue; 1484 continue;
1486 case SIGTERM: 1485 case SIGTERM:
1487 bb_error_msg("received %s", "SIGTERM"); 1486 bb_info_msg("received %s", "SIGTERM");
1488 goto ret0; 1487 goto ret0;
1489 } 1488 }
1490 1489
@@ -1496,15 +1495,15 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1496 int len; 1495 int len;
1497 1496
1498 /* A packet is ready, read it */ 1497 /* A packet is ready, read it */
1499 if (listen_mode == LISTEN_KERNEL) 1498 if (client_data.listen_mode == LISTEN_KERNEL)
1500 len = d6_recv_kernel_packet(&srv6_buf, &packet, sockfd); 1499 len = d6_recv_kernel_packet(&srv6_buf, &packet, client_data.sockfd);
1501 else 1500 else
1502 len = d6_recv_raw_packet(&srv6_buf, &packet, sockfd); 1501 len = d6_recv_raw_packet(&srv6_buf, &packet, client_data.sockfd);
1503 if (len == -1) { 1502 if (len == -1) {
1504 /* Error is severe, reopen socket */ 1503 /* Error is severe, reopen socket */
1505 bb_error_msg("read error: "STRERROR_FMT", reopening socket" STRERROR_ERRNO); 1504 bb_error_msg("read error: "STRERROR_FMT", reopening socket" STRERROR_ERRNO);
1506 sleep(discover_timeout); /* 3 seconds by default */ 1505 sleep(discover_timeout); /* 3 seconds by default */
1507 change_listen_mode(listen_mode); /* just close and reopen */ 1506 change_listen_mode(client_data.listen_mode); /* just close and reopen */
1508 } 1507 }
1509 /* If this packet will turn out to be unrelated/bogus, 1508 /* If this packet will turn out to be unrelated/bogus,
1510 * we will go back and wait for next one. 1509 * we will go back and wait for next one.
@@ -1521,7 +1520,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1521 continue; 1520 continue;
1522 } 1521 }
1523 1522
1524 switch (state) { 1523 switch (client_data.state) {
1525 case INIT_SELECTING: 1524 case INIT_SELECTING:
1526 if (packet.d6_msg_type == D6_MSG_ADVERTISE) 1525 if (packet.d6_msg_type == D6_MSG_ADVERTISE)
1527 goto type_is_ok; 1526 goto type_is_ok;
@@ -1544,15 +1543,15 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1544 option = d6_find_option(packet.d6_options, packet_end, D6_OPT_STATUS_CODE); 1543 option = d6_find_option(packet.d6_options, packet_end, D6_OPT_STATUS_CODE);
1545 if (option && (option->data[0] | option->data[1]) != 0) { 1544 if (option && (option->data[0] | option->data[1]) != 0) {
1546 /* return to init state */ 1545 /* return to init state */
1547 bb_error_msg("received DHCP NAK (%u)", option->data[4]); 1546 bb_info_msg("received DHCP NAK (%u)", option->data[4]);
1548 d6_run_script(packet.d6_options, 1547 d6_run_script(packet.d6_options,
1549 packet_end, "nak"); 1548 packet_end, "nak");
1550 if (state != REQUESTING) 1549 if (client_data.state != REQUESTING)
1551 d6_run_script_no_option("deconfig"); 1550 d6_run_script_no_option("deconfig");
1552 change_listen_mode(LISTEN_RAW); 1551 change_listen_mode(LISTEN_RAW);
1553 sleep(3); /* avoid excessive network traffic */ 1552 sleep(3); /* avoid excessive network traffic */
1554 state = INIT_SELECTING; 1553 client_data.state = INIT_SELECTING;
1555 client_config.first_secs = 0; /* make secs field count from 0 */ 1554 client_data.first_secs = 0; /* make secs field count from 0 */
1556 requested_ipv6 = NULL; 1555 requested_ipv6 = NULL;
1557 timeout = 0; 1556 timeout = 0;
1558 packet_num = 0; 1557 packet_num = 0;
@@ -1561,7 +1560,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1561 } 1560 }
1562 option = d6_copy_option(packet.d6_options, packet_end, D6_OPT_SERVERID); 1561 option = d6_copy_option(packet.d6_options, packet_end, D6_OPT_SERVERID);
1563 if (!option) { 1562 if (!option) {
1564 bb_error_msg("no server ID, ignoring packet"); 1563 bb_info_msg("no server ID, ignoring packet");
1565 continue; 1564 continue;
1566 /* still selecting - this server looks bad */ 1565 /* still selecting - this server looks bad */
1567 } 1566 }
@@ -1572,7 +1571,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1572 client6_data.server_id = option; 1571 client6_data.server_id = option;
1573 if (packet.d6_msg_type == D6_MSG_ADVERTISE) { 1572 if (packet.d6_msg_type == D6_MSG_ADVERTISE) {
1574 /* enter requesting state */ 1573 /* enter requesting state */
1575 state = REQUESTING; 1574 client_data.state = REQUESTING;
1576 timeout = 0; 1575 timeout = 0;
1577 packet_num = 0; 1576 packet_num = 0;
1578 already_waited_sec = 0; 1577 already_waited_sec = 0;
@@ -1670,11 +1669,11 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1670 free(client6_data.ia_na); 1669 free(client6_data.ia_na);
1671 client6_data.ia_na = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_NA); 1670 client6_data.ia_na = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_NA);
1672 if (!client6_data.ia_na) { 1671 if (!client6_data.ia_na) {
1673 bb_error_msg("no %s option, ignoring packet", "IA_NA"); 1672 bb_info_msg("no %s option, ignoring packet", "IA_NA");
1674 continue; 1673 continue;
1675 } 1674 }
1676 if (client6_data.ia_na->len < (4 + 4 + 4) + (2 + 2 + 16 + 4 + 4)) { 1675 if (client6_data.ia_na->len < (4 + 4 + 4) + (2 + 2 + 16 + 4 + 4)) {
1677 bb_error_msg("%s option is too short:%d bytes", 1676 bb_info_msg("%s option is too short:%d bytes",
1678 "IA_NA", client6_data.ia_na->len); 1677 "IA_NA", client6_data.ia_na->len);
1679 continue; 1678 continue;
1680 } 1679 }
@@ -1683,11 +1682,11 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1683 D6_OPT_IAADDR 1682 D6_OPT_IAADDR
1684 ); 1683 );
1685 if (!iaaddr) { 1684 if (!iaaddr) {
1686 bb_error_msg("no %s option, ignoring packet", "IAADDR"); 1685 bb_info_msg("no %s option, ignoring packet", "IAADDR");
1687 continue; 1686 continue;
1688 } 1687 }
1689 if (iaaddr->len < (16 + 4 + 4)) { 1688 if (iaaddr->len < (16 + 4 + 4)) {
1690 bb_error_msg("%s option is too short:%d bytes", 1689 bb_info_msg("%s option is too short:%d bytes",
1691 "IAADDR", iaaddr->len); 1690 "IAADDR", iaaddr->len);
1692 continue; 1691 continue;
1693 } 1692 }
@@ -1698,7 +1697,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1698 move_from_unaligned32(lease_seconds, iaaddr->data + 16 + 4); 1697 move_from_unaligned32(lease_seconds, iaaddr->data + 16 + 4);
1699 lease_seconds = ntohl(lease_seconds); 1698 lease_seconds = ntohl(lease_seconds);
1700/// TODO: check for 0 lease time? 1699/// TODO: check for 0 lease time?
1701 bb_error_msg("%s obtained, lease time %u", 1700 bb_info_msg("%s obtained, lease time %u",
1702 "IPv6", /*inet_ntoa(temp_addr),*/ (unsigned)lease_seconds); 1701 "IPv6", /*inet_ntoa(temp_addr),*/ (unsigned)lease_seconds);
1703 address_timeout = lease_seconds; 1702 address_timeout = lease_seconds;
1704 } 1703 }
@@ -1708,11 +1707,11 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1708 free(client6_data.ia_pd); 1707 free(client6_data.ia_pd);
1709 client6_data.ia_pd = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_PD); 1708 client6_data.ia_pd = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_PD);
1710 if (!client6_data.ia_pd) { 1709 if (!client6_data.ia_pd) {
1711 bb_error_msg("no %s option, ignoring packet", "IA_PD"); 1710 bb_info_msg("no %s option, ignoring packet", "IA_PD");
1712 continue; 1711 continue;
1713 } 1712 }
1714 if (client6_data.ia_pd->len < (4 + 4 + 4) + (2 + 2 + 4 + 4 + 1 + 16)) { 1713 if (client6_data.ia_pd->len < (4 + 4 + 4) + (2 + 2 + 4 + 4 + 1 + 16)) {
1715 bb_error_msg("%s option is too short:%d bytes", 1714 bb_info_msg("%s option is too short:%d bytes",
1716 "IA_PD", client6_data.ia_pd->len); 1715 "IA_PD", client6_data.ia_pd->len);
1717 continue; 1716 continue;
1718 } 1717 }
@@ -1721,17 +1720,17 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1721 D6_OPT_IAPREFIX 1720 D6_OPT_IAPREFIX
1722 ); 1721 );
1723 if (!iaprefix) { 1722 if (!iaprefix) {
1724 bb_error_msg("no %s option, ignoring packet", "IAPREFIX"); 1723 bb_info_msg("no %s option, ignoring packet", "IAPREFIX");
1725 continue; 1724 continue;
1726 } 1725 }
1727 if (iaprefix->len < (4 + 4 + 1 + 16)) { 1726 if (iaprefix->len < (4 + 4 + 1 + 16)) {
1728 bb_error_msg("%s option is too short:%d bytes", 1727 bb_info_msg("%s option is too short:%d bytes",
1729 "IAPREFIX", iaprefix->len); 1728 "IAPREFIX", iaprefix->len);
1730 continue; 1729 continue;
1731 } 1730 }
1732 move_from_unaligned32(lease_seconds, iaprefix->data + 4); 1731 move_from_unaligned32(lease_seconds, iaprefix->data + 4);
1733 lease_seconds = ntohl(lease_seconds); 1732 lease_seconds = ntohl(lease_seconds);
1734 bb_error_msg("%s obtained, lease time %u", 1733 bb_info_msg("%s obtained, lease time %u",
1735 "prefix", /*inet_ntoa(temp_addr),*/ (unsigned)lease_seconds); 1734 "prefix", /*inet_ntoa(temp_addr),*/ (unsigned)lease_seconds);
1736 prefix_timeout = lease_seconds; 1735 prefix_timeout = lease_seconds;
1737 } 1736 }
@@ -1747,9 +1746,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1747 timeout = 61; 1746 timeout = 61;
1748 /* enter bound state */ 1747 /* enter bound state */
1749 d6_run_script(packet.d6_options, packet_end, 1748 d6_run_script(packet.d6_options, packet_end,
1750 (state == REQUESTING ? "bound" : "renew")); 1749 (client_data.state == REQUESTING ? "bound" : "renew"));
1751 1750
1752 state = BOUND; 1751 client_data.state = BOUND;
1753 change_listen_mode(LISTEN_NONE); 1752 change_listen_mode(LISTEN_NONE);
1754 if (opt & OPT_q) { /* quit after lease */ 1753 if (opt & OPT_q) { /* quit after lease */
1755 goto ret0; 1754 goto ret0;
@@ -1778,7 +1777,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1778 perform_d6_release(&srv6_buf, requested_ipv6); 1777 perform_d6_release(&srv6_buf, requested_ipv6);
1779 retval = 0; 1778 retval = 0;
1780 ret: 1779 ret:
1781 /*if (client_config.pidfile) - remove_pidfile has its own check */ 1780 /*if (client_data.pidfile) - remove_pidfile has its own check */
1782 remove_pidfile(client_config.pidfile); 1781 remove_pidfile(client_data.pidfile);
1783 return retval; 1782 return retval;
1784} 1783}