diff options
author | Ron Yorston <rmy@pobox.com> | 2023-01-05 08:56:27 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-01-05 08:56:27 +0000 |
commit | e5e4a2fec5435192d1672e6db2f335cb5e89f877 (patch) | |
tree | 08cb827a40817ea4824bc9336d57eda669c4d4b2 /networking | |
parent | 4343f3926355f55fc023203c992527fc34bf609e (diff) | |
parent | b1884deb514c35289d37e7bfbf23f770b0bd09b3 (diff) | |
download | busybox-w32-e5e4a2fec5435192d1672e6db2f335cb5e89f877.tar.gz busybox-w32-e5e4a2fec5435192d1672e6db2f335cb5e89f877.tar.bz2 busybox-w32-e5e4a2fec5435192d1672e6db2f335cb5e89f877.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'networking')
-rw-r--r-- | networking/udhcp/Config.src | 7 | ||||
-rw-r--r-- | networking/udhcp/common.h | 3 | ||||
-rw-r--r-- | networking/udhcp/d6_common.h | 41 | ||||
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 17 | ||||
-rw-r--r-- | networking/udhcp/d6_packet.c | 15 | ||||
-rw-r--r-- | networking/udhcp/d6_socket.c | 13 | ||||
-rw-r--r-- | networking/udhcp/packet.c | 1 |
7 files changed, 72 insertions, 25 deletions
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src index 8c8c11c26..7ba7f48fc 100644 --- a/networking/udhcp/Config.src +++ b/networking/udhcp/Config.src | |||
@@ -92,12 +92,17 @@ config FEATURE_UDHCPC_SANITIZEOPT | |||
92 | config UDHCPC_DEFAULT_SCRIPT | 92 | config UDHCPC_DEFAULT_SCRIPT |
93 | string "Absolute path to config script" | 93 | string "Absolute path to config script" |
94 | default "/usr/share/udhcpc/default.script" | 94 | default "/usr/share/udhcpc/default.script" |
95 | depends on UDHCPC || UDHCPC6 | 95 | depends on UDHCPC |
96 | help | 96 | help |
97 | This script is called after udhcpc receives an answer. See | 97 | This script is called after udhcpc receives an answer. See |
98 | examples/udhcp for a working example. Normally it is safe | 98 | examples/udhcp for a working example. Normally it is safe |
99 | to leave this untouched. | 99 | to leave this untouched. |
100 | 100 | ||
101 | config UDHCPC6_DEFAULT_SCRIPT | ||
102 | string "Absolute path to config script for IPv6" | ||
103 | default "/usr/share/udhcpc/default6.script" | ||
104 | depends on UDHCPC6 | ||
105 | |||
101 | # udhcpc6 config is inserted here: | 106 | # udhcpc6 config is inserted here: |
102 | INSERT | 107 | INSERT |
103 | 108 | ||
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 5882238e3..49a0b593d 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -370,7 +370,8 @@ void udhcp_sp_setup(void) FAST_FUNC; | |||
370 | void udhcp_sp_fd_set(struct pollfd *pfds, int extra_fd) FAST_FUNC; | 370 | void udhcp_sp_fd_set(struct pollfd *pfds, int extra_fd) FAST_FUNC; |
371 | int udhcp_sp_read(void) FAST_FUNC; | 371 | int udhcp_sp_read(void) FAST_FUNC; |
372 | 372 | ||
373 | int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac) FAST_FUNC; | 373 | int udhcp_read_interface(const char *interface, |
374 | int *ifindex, uint32_t *nip, uint8_t *mac) FAST_FUNC; | ||
374 | 375 | ||
375 | int udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) FAST_FUNC; | 376 | int udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) FAST_FUNC; |
376 | 377 | ||
diff --git a/networking/udhcp/d6_common.h b/networking/udhcp/d6_common.h index 9dfde7709..3cbfbb89e 100644 --- a/networking/udhcp/d6_common.h +++ b/networking/udhcp/d6_common.h | |||
@@ -63,28 +63,45 @@ struct d6_option { | |||
63 | 63 | ||
64 | #define D6_OPT_CLIENTID 1 | 64 | #define D6_OPT_CLIENTID 1 |
65 | #define D6_OPT_SERVERID 2 | 65 | #define D6_OPT_SERVERID 2 |
66 | /* "Identity Association for Non-temporary Addresses", | ||
67 | * also known as a "network interface" in plain English */ | ||
66 | #define D6_OPT_IA_NA 3 | 68 | #define D6_OPT_IA_NA 3 |
67 | #define D6_OPT_IA_TA 4 | 69 | /* "Identity Association for the Temporary Addresses". |
70 | * Presumably this is a "network interface with only link-local addresses". | ||
71 | * Why would DHCPv6 server assign such addresses, I have no idea. */ | ||
72 | //#define D6_OPT_IA_TA 4 | ||
73 | /* "IA Address", an IPv6 address */ | ||
68 | #define D6_OPT_IAADDR 5 | 74 | #define D6_OPT_IAADDR 5 |
75 | /* Option "Option Request Option". From the owners of a doggy dog named Dog? */ | ||
69 | #define D6_OPT_ORO 6 | 76 | #define D6_OPT_ORO 6 |
70 | #define D6_OPT_PREFERENCE 7 | 77 | //#define D6_OPT_PREFERENCE 7 |
71 | #define D6_OPT_ELAPSED_TIME 8 | 78 | #define D6_OPT_ELAPSED_TIME 8 |
72 | #define D6_OPT_RELAY_MSG 9 | 79 | //#define D6_OPT_RELAY_MSG 9 |
73 | #define D6_OPT_AUTH 11 | 80 | //#define D6_OPT_AUTH 11 |
74 | #define D6_OPT_UNICAST 12 | 81 | /* "The server sends this option to a client to indicate to the client |
82 | * that it is allowed to unicast messages to the server." | ||
83 | * Contains IPv6 address to send packets to. */ | ||
84 | //#define D6_OPT_UNICAST 12 | ||
85 | /* "A Status Code option may appear in the options field of a DHCP | ||
86 | * message and/or in the options field of another option." */ | ||
75 | #define D6_OPT_STATUS_CODE 13 | 87 | #define D6_OPT_STATUS_CODE 13 |
76 | #define D6_OPT_RAPID_COMMIT 14 | 88 | /* "A client MAY include this option in a Solicit message if the client |
77 | #define D6_OPT_USER_CLASS 15 | 89 | * is prepared to perform the Solicit-Reply message exchange..." */ |
78 | #define D6_OPT_VENDOR_CLASS 16 | 90 | //#define D6_OPT_RAPID_COMMIT 14 /* zero-length option */ |
79 | #define D6_OPT_VENDOR_OPTS 17 | 91 | //#define D6_OPT_USER_CLASS 15 |
80 | #define D6_OPT_INTERFACE_ID 18 | 92 | //#define D6_OPT_VENDOR_CLASS 16 |
81 | #define D6_OPT_RECONF_MSG 19 | 93 | //#define D6_OPT_VENDOR_OPTS 17 |
82 | #define D6_OPT_RECONF_ACCEPT 20 | 94 | //#define D6_OPT_INTERFACE_ID 18 |
95 | //#define D6_OPT_RECONF_MSG 19 | ||
96 | //#define D6_OPT_RECONF_ACCEPT 20 | ||
83 | 97 | ||
84 | #define D6_OPT_DNS_SERVERS 23 | 98 | #define D6_OPT_DNS_SERVERS 23 |
85 | #define D6_OPT_DOMAIN_LIST 24 | 99 | #define D6_OPT_DOMAIN_LIST 24 |
86 | 100 | ||
101 | /* RFC 3633 "Identity Association for Prefix Delegation". | ||
102 | * This option says that client wants to get an IPv6 prefix */ | ||
87 | #define D6_OPT_IA_PD 25 | 103 | #define D6_OPT_IA_PD 25 |
104 | /* Response from the server comes in this one */ | ||
88 | #define D6_OPT_IAPREFIX 26 | 105 | #define D6_OPT_IAPREFIX 26 |
89 | 106 | ||
90 | /* RFC 4704 "The DHCPv6 Client FQDN Option" | 107 | /* RFC 4704 "The DHCPv6 Client FQDN Option" |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index c7f130a70..cdd06188e 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
@@ -548,7 +548,7 @@ static uint8_t *add_d6_client_options(uint8_t *ptr) | |||
548 | static int d6_mcast_from_client_data_ifindex(struct d6_packet *packet, uint8_t *end) | 548 | static int d6_mcast_from_client_data_ifindex(struct d6_packet *packet, uint8_t *end) |
549 | { | 549 | { |
550 | /* FF02::1:2 is "All_DHCP_Relay_Agents_and_Servers" address */ | 550 | /* FF02::1:2 is "All_DHCP_Relay_Agents_and_Servers" address */ |
551 | static const uint8_t FF02__1_2[16] = { | 551 | static const uint8_t FF02__1_2[16] ALIGNED(sizeof(long)) = { |
552 | 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 552 | 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
553 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, | 553 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, |
554 | }; | 554 | }; |
@@ -890,7 +890,6 @@ int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6) | |||
890 | if (client6_data.ia_pd) | 890 | if (client6_data.ia_pd) |
891 | opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, client6_data.ia_pd->len + 2+2); | 891 | opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, client6_data.ia_pd->len + 2+2); |
892 | /* Client-id */ | 892 | /* Client-id */ |
893 | ///vda | ||
894 | ci = udhcp_find_option(client_data.options, D6_OPT_CLIENTID, /*dhcpv6:*/ 1); | 893 | ci = udhcp_find_option(client_data.options, D6_OPT_CLIENTID, /*dhcpv6:*/ 1); |
895 | if (ci) | 894 | if (ci) |
896 | opt_ptr = mempcpy(opt_ptr, ci->data, D6_OPT_DATA + 2+2 + 6); | 895 | opt_ptr = mempcpy(opt_ptr, ci->data, D6_OPT_DATA + 2+2 + 6); |
@@ -1135,7 +1134,7 @@ static void client_background(void) | |||
1135 | //usage:#define udhcpc6_full_usage "\n" | 1134 | //usage:#define udhcpc6_full_usage "\n" |
1136 | //usage: "\n -i IFACE Interface to use (default "CONFIG_UDHCPC_DEFAULT_INTERFACE")" | 1135 | //usage: "\n -i IFACE Interface to use (default "CONFIG_UDHCPC_DEFAULT_INTERFACE")" |
1137 | //usage: "\n -p FILE Create pidfile" | 1136 | //usage: "\n -p FILE Create pidfile" |
1138 | //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")" | 1137 | //usage: "\n -s PROG Run PROG at DHCP events (default "CONFIG_UDHCPC6_DEFAULT_SCRIPT")" |
1139 | //usage: "\n -B Request broadcast replies" | 1138 | //usage: "\n -B Request broadcast replies" |
1140 | //usage: "\n -t N Send up to N discover packets" | 1139 | //usage: "\n -t N Send up to N discover packets" |
1141 | //usage: "\n -T SEC Pause between packets (default 3)" | 1140 | //usage: "\n -T SEC Pause between packets (default 3)" |
@@ -1201,7 +1200,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1201 | IF_FEATURE_UDHCP_PORT(SERVER_PORT6 = 547;) | 1200 | IF_FEATURE_UDHCP_PORT(SERVER_PORT6 = 547;) |
1202 | IF_FEATURE_UDHCP_PORT(CLIENT_PORT6 = 546;) | 1201 | IF_FEATURE_UDHCP_PORT(CLIENT_PORT6 = 546;) |
1203 | client_data.interface = CONFIG_UDHCPC_DEFAULT_INTERFACE; | 1202 | client_data.interface = CONFIG_UDHCPC_DEFAULT_INTERFACE; |
1204 | client_data.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; | 1203 | client_data.script = CONFIG_UDHCPC6_DEFAULT_SCRIPT; |
1205 | client_data.sockfd = -1; | 1204 | client_data.sockfd = -1; |
1206 | 1205 | ||
1207 | /* Make sure fd 0,1,2 are open */ | 1206 | /* Make sure fd 0,1,2 are open */ |
@@ -1618,6 +1617,16 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1618 | prefix_timeout = 0; | 1617 | prefix_timeout = 0; |
1619 | option = d6_find_option(packet.d6_options, packet_end, D6_OPT_STATUS_CODE); | 1618 | option = d6_find_option(packet.d6_options, packet_end, D6_OPT_STATUS_CODE); |
1620 | if (option && (option->data[0] | option->data[1]) != 0) { | 1619 | if (option && (option->data[0] | option->data[1]) != 0) { |
1620 | ///FIXME: | ||
1621 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1622 | // | OPTION_STATUS_CODE | option-len | | ||
1623 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1624 | // | status-code | | | ||
1625 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | ||
1626 | // . status-message . | ||
1627 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
1628 | // so why do we think it's NAK if data[0] is zero but data[1] is not? That's wrong... | ||
1629 | // we should also check that option->len is ok (i.e. not 0), right? | ||
1621 | /* return to init state */ | 1630 | /* return to init state */ |
1622 | bb_info_msg("received DHCP NAK (%u)", option->data[4]); | 1631 | bb_info_msg("received DHCP NAK (%u)", option->data[4]); |
1623 | d6_run_script(packet.d6_options, | 1632 | d6_run_script(packet.d6_options, |
diff --git a/networking/udhcp/d6_packet.c b/networking/udhcp/d6_packet.c index c1949f6e3..142de9b43 100644 --- a/networking/udhcp/d6_packet.c +++ b/networking/udhcp/d6_packet.c | |||
@@ -27,9 +27,8 @@ void FAST_FUNC d6_dump_packet(struct d6_packet *packet) | |||
27 | } | 27 | } |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | int FAST_FUNC d6_recv_kernel_packet(struct in6_addr *peer_ipv6 | 30 | int FAST_FUNC d6_recv_kernel_packet(struct in6_addr *peer_ipv6 UNUSED_PARAM, |
31 | UNUSED_PARAM | 31 | struct d6_packet *packet, int fd) |
32 | , struct d6_packet *packet, int fd) | ||
33 | { | 32 | { |
34 | int bytes; | 33 | int bytes; |
35 | 34 | ||
@@ -81,12 +80,22 @@ int FAST_FUNC d6_send_raw_packet_from_client_data_ifindex( | |||
81 | dest_sll.sll_halen = 6; | 80 | dest_sll.sll_halen = 6; |
82 | memcpy(dest_sll.sll_addr, dest_arp, 6); | 81 | memcpy(dest_sll.sll_addr, dest_arp, 6); |
83 | 82 | ||
83 | //TODO: is bind() necessary? we sendto() to this destination, should work anyway | ||
84 | if (bind(fd, (struct sockaddr *)&dest_sll, sizeof(dest_sll)) < 0) { | 84 | if (bind(fd, (struct sockaddr *)&dest_sll, sizeof(dest_sll)) < 0) { |
85 | msg = "bind(%s)"; | 85 | msg = "bind(%s)"; |
86 | goto ret_close; | 86 | goto ret_close; |
87 | } | 87 | } |
88 | 88 | ||
89 | packet.ip6.ip6_vfc = (6 << 4); /* 4 bits version, top 4 bits of tclass */ | 89 | packet.ip6.ip6_vfc = (6 << 4); /* 4 bits version, top 4 bits of tclass */ |
90 | // In case we have no IPv6 on our interface at all, we can try | ||
91 | // to fill "all hosts" mcast address as source: | ||
92 | // /* FF02::1 is Link-local "All_Nodes" address */ | ||
93 | // packet.ip6.ip6_dst.s6_addr[0] = 0xff; | ||
94 | // packet.ip6.ip6_dst.s6_addr[1] = 0x02; | ||
95 | // packet.ip6.ip6_dst.s6_addr[15] = 0x01; | ||
96 | // Maybe some servers will be able to respond to us this way? | ||
97 | // Users report that leaving ::0 address there makes servers try to reply to ::0, | ||
98 | // which doesn't work. | ||
90 | if (src_ipv6) | 99 | if (src_ipv6) |
91 | packet.ip6.ip6_src = *src_ipv6; /* struct copy */ | 100 | packet.ip6.ip6_src = *src_ipv6; /* struct copy */ |
92 | packet.ip6.ip6_dst = *dst_ipv6; /* struct copy */ | 101 | packet.ip6.ip6_dst = *dst_ipv6; /* struct copy */ |
diff --git a/networking/udhcp/d6_socket.c b/networking/udhcp/d6_socket.c index 21cf61c6e..acf108367 100644 --- a/networking/udhcp/d6_socket.c +++ b/networking/udhcp/d6_socket.c | |||
@@ -95,9 +95,6 @@ int FAST_FUNC d6_read_interface( | |||
95 | close(fd); | 95 | close(fd); |
96 | } | 96 | } |
97 | 97 | ||
98 | if (retval == 0) | ||
99 | return retval; | ||
100 | |||
101 | if (retval & (1<<0)) | 98 | if (retval & (1<<0)) |
102 | bb_error_msg("can't get %s", "MAC"); | 99 | bb_error_msg("can't get %s", "MAC"); |
103 | if (retval & (1<<1)) | 100 | if (retval & (1<<1)) |
@@ -109,6 +106,7 @@ int FAST_FUNC d6_listen_socket(int port, const char *inf) | |||
109 | { | 106 | { |
110 | int fd; | 107 | int fd; |
111 | struct sockaddr_in6 addr; | 108 | struct sockaddr_in6 addr; |
109 | char *colon; | ||
112 | 110 | ||
113 | log2("opening listen socket on *:%d %s", port, inf); | 111 | log2("opening listen socket on *:%d %s", port, inf); |
114 | fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); | 112 | fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); |
@@ -117,10 +115,17 @@ int FAST_FUNC d6_listen_socket(int port, const char *inf) | |||
117 | if (setsockopt_broadcast(fd) == -1) | 115 | if (setsockopt_broadcast(fd) == -1) |
118 | bb_simple_perror_msg_and_die("SO_BROADCAST"); | 116 | bb_simple_perror_msg_and_die("SO_BROADCAST"); |
119 | 117 | ||
120 | /* NB: bug 1032 says this doesn't work on ethernet aliases (ethN:M) */ | 118 | /* SO_BINDTODEVICE doesn't work on ethernet aliases (ethN:M) */ |
119 | colon = strrchr(inf, ':'); | ||
120 | if (colon) | ||
121 | *colon = '\0'; | ||
122 | |||
121 | if (setsockopt_bindtodevice(fd, inf)) | 123 | if (setsockopt_bindtodevice(fd, inf)) |
122 | xfunc_die(); /* warning is already printed */ | 124 | xfunc_die(); /* warning is already printed */ |
123 | 125 | ||
126 | if (colon) | ||
127 | *colon = ':'; | ||
128 | |||
124 | memset(&addr, 0, sizeof(addr)); | 129 | memset(&addr, 0, sizeof(addr)); |
125 | addr.sin6_family = AF_INET6; | 130 | addr.sin6_family = AF_INET6; |
126 | addr.sin6_port = htons(port); | 131 | addr.sin6_port = htons(port); |
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index 78f580ce9..529978189 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c | |||
@@ -133,6 +133,7 @@ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt, | |||
133 | dest_sll.sll_halen = 6; | 133 | dest_sll.sll_halen = 6; |
134 | memcpy(dest_sll.sll_addr, dest_arp, 6); | 134 | memcpy(dest_sll.sll_addr, dest_arp, 6); |
135 | 135 | ||
136 | //TODO: is bind() necessary? we sendto() to this destination, should work anyway | ||
136 | if (bind(fd, (struct sockaddr *)&dest_sll, sizeof(dest_sll)) < 0) { | 137 | if (bind(fd, (struct sockaddr *)&dest_sll, sizeof(dest_sll)) < 0) { |
137 | msg = "bind(%s)"; | 138 | msg = "bind(%s)"; |
138 | goto ret_close; | 139 | goto ret_close; |