aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-01-05 08:56:27 +0000
committerRon Yorston <rmy@pobox.com>2023-01-05 08:56:27 +0000
commite5e4a2fec5435192d1672e6db2f335cb5e89f877 (patch)
tree08cb827a40817ea4824bc9336d57eda669c4d4b2 /networking
parent4343f3926355f55fc023203c992527fc34bf609e (diff)
parentb1884deb514c35289d37e7bfbf23f770b0bd09b3 (diff)
downloadbusybox-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.src7
-rw-r--r--networking/udhcp/common.h3
-rw-r--r--networking/udhcp/d6_common.h41
-rw-r--r--networking/udhcp/d6_dhcpc.c17
-rw-r--r--networking/udhcp/d6_packet.c15
-rw-r--r--networking/udhcp/d6_socket.c13
-rw-r--r--networking/udhcp/packet.c1
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
92config UDHCPC_DEFAULT_SCRIPT 92config 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
101config 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:
102INSERT 107INSERT
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;
370void udhcp_sp_fd_set(struct pollfd *pfds, int extra_fd) FAST_FUNC; 370void udhcp_sp_fd_set(struct pollfd *pfds, int extra_fd) FAST_FUNC;
371int udhcp_sp_read(void) FAST_FUNC; 371int udhcp_sp_read(void) FAST_FUNC;
372 372
373int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac) FAST_FUNC; 373int udhcp_read_interface(const char *interface,
374 int *ifindex, uint32_t *nip, uint8_t *mac) FAST_FUNC;
374 375
375int udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) FAST_FUNC; 376int 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)
548static int d6_mcast_from_client_data_ifindex(struct d6_packet *packet, uint8_t *end) 548static 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
30int FAST_FUNC d6_recv_kernel_packet(struct in6_addr *peer_ipv6 30int 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;