diff options
Diffstat (limited to 'networking/udhcp/d6_dhcpc.c')
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 201 |
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 | ||
68 | static const struct dhcp_optflag d6_optflags[] = { | 68 | static 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 | ||
531 | static int d6_mcast_from_client_config_ifindex(struct d6_packet *packet, uint8_t *end) | 531 | static 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 | ||
906 | static 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 |
911 | static 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 |
927 | static smallint state; | ||
928 | 926 | ||
929 | static int d6_raw_socket(int ifindex) | 927 | static 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 */ |
1034 | static void perform_renew(void) | 1032 | static 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) | |||
1056 | static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) | 1054 | static 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 | } |