Hey there, this is my first post on the list and my first set of patches I wrote for busybox, so please forgive me if I'm missing something.
We are currently trying to build an IPv6-only-environment with statefull autoconfiguration using busybox-udhcpc6 on client-side. During development I was wondering if anyone out there might be using udhcpc6 as well es we encountered some severe bugs. This weekend I shared an initial patch on bugzilla [0], but had to find out some time later that someone already has done it years ago here on the mailinglist [1] - although the patch didn't make it into any release. At the moment the vanilla udhcpc6 uses a null-source-address when asking for dhcp6-autoconfiguration. As already said on the ticket and on the referenced mailinglist-post, this behaviour is wrong as the link-local-address of the interface should be used and any interface is supposed to have one. You'll find our patch attached to this e-mail (udhcpc-read-ipv6.patch) that has evolved since the post on bugzilla and is similar to the patch by Mathias Krüger - it also utilizes getifaddrs() but instead of using a new additional function, we had rewritten udhcp_read_interface(). Using this patch it was no problem to acquire an IPv6-Address via DHCPv6 using ISC DHCPD6 on server-side. But when we tried to use dnsmasq on server-side, udhcpc6 was unable to forward the acquired address to its setup-script although the IPv6-Address had been assigned by the server as we could see via tcpdump. We traced this issue down to a problem on how udhcpc6 parses DHCPv6-Options: When moving to next option, a pointer-address is increased and a length buffer is decreased by the length of the option. The problem is that it is done in this order: option += 4 + option[3]; len_m4 -= 4 + option[3]; But this has to be switched as the length is decreased by the length of the *next* option, not the current one. This affected both - internal checks if a required option is present and the function to expose options to the environment of the setup-script. There was also a bug parsing D6_OPT_STATUS_CODE Options, that made dnsmasq not work as udhcpc6 thought it is receiving a non-positive status-code (because it did not parse the status-code as required in RFC 3315). In addition we introduced basic support for RFC 3646 (OPTION_DNS_SERVERS and OPTION_DOMAIN_LIST) and RFC 4704 (OPTION_CLIENT_FQDN). All this option-related patches are located in the attached udhcpc-v6-options.patch. Last but not least: We wanted udhcpc6 to release it's IPv6-Addresses on quit (-R-commandline-option) which turned out to generate once again kind of garbage on the network-link. We tracked this down to two issues: - udhcpc6 uses a variable called "srv6_buf" to send packets to the dhcp6-server, but this variable gets never initialized correctly and contained kind of a garbage-address - The address of the dhcp6-server is usually a link-local-address, that requires an interface-index when using connect() on an AF_INET6- socket In the attached patch "udhcpc-fix-kernel-send.patch" we added an additional parameter for ifindex to d6_send_kernel_packet() and made d6_recv_raw_packet() to capture the address of the dhcp6-server and forward it to its callee. With these three patches applied busybox just worked like a charme in our IPv6-only-environment. The patches may required some review, but I would be very happy if you find them useful, too. Kind regards, Bernd [0] https://bugs.busybox.net/show_bug.cgi?id=6194 [1] http://lists.busybox.net/pipermail/busybox/2013-August/079703.html -- \\\||/// \\ - - // ( @ @ ) -oOo--( )--oOo------------------------------------------------------- tiggersWelt.net www.tiggersWelt.net Inhaber Bernd Holzmüller [email protected] Büro: 07 11 / 550 425-90 Marktstraße 57 Fax: 07 11 / 550 425-99 70372 Stuttgart
diff -Nru busybox-1.26.2.org/networking/udhcp/common.h busybox-1.26.2.mod/networking/udhcp/common.h
--- busybox-1.26.2.org/networking/udhcp/common.h 2016-09-27 18:53:50.000000000 +0200
+++ busybox-1.26.2.mod/networking/udhcp/common.h 2017-03-06 19:38:31.076316233 +0100
@@ -303,7 +303,7 @@
int udhcp_sp_fd_set(fd_set *rfds, int extra_fd) FAST_FUNC;
int udhcp_sp_read(const fd_set *rfds) FAST_FUNC;
-int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac) FAST_FUNC;
+int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, struct in6_addr **nip6, uint8_t *mac) FAST_FUNC;
int udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) FAST_FUNC;
diff -Nru busybox-1.26.2.org/networking/udhcp/d6_common.h busybox-1.26.2.mod/networking/udhcp/d6_common.h
--- busybox-1.26.2.org/networking/udhcp/d6_common.h 2016-09-27 18:53:50.000000000 +0200
+++ busybox-1.26.2.mod/networking/udhcp/d6_common.h 2017-03-06 20:14:11.636939559 +0100
@@ -91,6 +96,7 @@
struct d6_option *ia_na;
char **env_ptr;
unsigned env_idx;
+ struct in6_addr *ll_addr;
};
#define client6_data (*(struct client6_data_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE - sizeof(struct client6_data_t)]))
diff -Nru busybox-1.26.2.org/networking/udhcp/d6_dhcpc.c busybox-1.26.2.mod/networking/udhcp/d6_dhcpc.c
--- busybox-1.26.2.org/networking/udhcp/d6_dhcpc.c 2016-09-27 18:53:50.000000000 +0200
+++ busybox-1.26.2.mod/networking/udhcp/d6_dhcpc.c 2017-03-06 20:16:58.441939869 +0100
@@ -308,10 +369,10 @@
0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
};
-
+
return d6_send_raw_packet(
packet, (end - (uint8_t*) packet),
- /*src*/ NULL, CLIENT_PORT6,
+ /*src*/ client6_data.ll_addr, CLIENT_PORT6,
/*dst*/ (struct in6_addr*)FF02__1_2, SERVER_PORT6, MAC_BCAST_ADDR,
client_config.ifindex
);
@@ -1008,6 +1079,7 @@
if (udhcp_read_interface(client_config.interface,
&client_config.ifindex,
NULL,
+ &client6_data.ll_addr,
client_config.client_mac)
) {
return 1;
@@ -1111,10 +1183,12 @@
if (udhcp_read_interface(client_config.interface,
&client_config.ifindex,
NULL,
+ &client6_data.ll_addr,
client_config.client_mac)
) {
goto ret0; /* iface is gone? */
}
+
memcpy(clientid_mac_ptr, client_config.client_mac, 6);
/* We will restart the wait in any case */
diff -Nru busybox-1.26.2.org/networking/udhcp/dhcpc.c busybox-1.26.2.mod/networking/udhcp/dhcpc.c
--- busybox-1.26.2.org/networking/udhcp/dhcpc.c 2016-12-10 18:46:36.000000000 +0100
+++ busybox-1.26.2.mod/networking/udhcp/dhcpc.c 2017-03-06 19:38:31.076316233 +0100
@@ -1372,6 +1372,7 @@
if (udhcp_read_interface(client_config.interface,
&client_config.ifindex,
NULL,
+ NULL,
client_config.client_mac)
) {
return 1;
@@ -1479,6 +1480,7 @@
if (udhcp_read_interface(client_config.interface,
&client_config.ifindex,
NULL,
+ NULL,
client_config.client_mac)
) {
goto ret0; /* iface is gone? */
diff -Nru busybox-1.26.2.org/networking/udhcp/dhcpd.c busybox-1.26.2.mod/networking/udhcp/dhcpd.c
--- busybox-1.26.2.org/networking/udhcp/dhcpd.c 2016-12-10 18:46:36.000000000 +0100
+++ busybox-1.26.2.mod/networking/udhcp/dhcpd.c 2017-03-06 19:38:31.076316233 +0100
@@ -879,6 +879,7 @@
if (udhcp_read_interface(server_config.interface,
&server_config.ifindex,
(server_config.server_nip == 0 ? &server_config.server_nip : NULL),
+ NULL,
server_config.server_mac)
) {
retval = 1;
diff -Nru busybox-1.26.2.org/networking/udhcp/dhcprelay.c busybox-1.26.2.mod/networking/udhcp/dhcprelay.c
--- busybox-1.26.2.org/networking/udhcp/dhcprelay.c 2016-12-10 18:46:36.000000000 +0100
+++ busybox-1.26.2.mod/networking/udhcp/dhcprelay.c 2017-03-06 19:38:31.076316233 +0100
@@ -283,7 +283,7 @@
max_socket = init_sockets(iface_list, num_sockets, fds);
/* Get our IP on server_iface */
- if (udhcp_read_interface(argv[2], NULL, &our_nip, NULL))
+ if (udhcp_read_interface(argv[2], NULL, &our_nip, NULL, NULL))
return 1;
/* Main loop */
@@ -363,7 +363,7 @@
// of the 'giaddr' field does not match one of the relay agent's
// directly-connected logical interfaces, the BOOTREPLY messsage MUST be
// silently discarded.
- if (udhcp_read_interface(iface_list[i], NULL, &dhcp_msg.gateway_nip, NULL)) {
+ if (udhcp_read_interface(iface_list[i], NULL, &dhcp_msg.gateway_nip, NULL, NULL)) {
/* Fall back to our IP on server iface */
// this makes more sense!
dhcp_msg.gateway_nip = our_nip;
diff -Nru busybox-1.26.2.org/networking/udhcp/socket.c busybox-1.26.2.mod/networking/udhcp/socket.c
--- busybox-1.26.2.org/networking/udhcp/socket.c 2016-09-27 18:53:50.000000000 +0200
+++ busybox-1.26.2.mod/networking/udhcp/socket.c 2017-03-06 20:05:28.853795123 +0100
@@ -24,54 +24,52 @@
*/
#include "common.h"
#include <net/if.h>
+#include <ifaddrs.h>
+#include <netpacket/packet.h>
-int FAST_FUNC udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac)
-{
- /* char buffer instead of bona-fide struct avoids aliasing warning */
- char ifr_buf[sizeof(struct ifreq)];
- struct ifreq *const ifr = (void *)ifr_buf;
-
- int fd;
- struct sockaddr_in *our_ip;
-
- memset(ifr, 0, sizeof(*ifr));
- fd = xsocket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-
- ifr->ifr_addr.sa_family = AF_INET;
- strncpy_IFNAMSIZ(ifr->ifr_name, interface);
- if (nip) {
- if (ioctl_or_perror(fd, SIOCGIFADDR, ifr,
- "is interface %s up and configured?", interface)
- ) {
- close(fd);
- return -1;
- }
- our_ip = (struct sockaddr_in *) &ifr->ifr_addr;
- *nip = our_ip->sin_addr.s_addr;
- log1("IP %s", inet_ntoa(our_ip->sin_addr));
- }
-
- if (ifindex) {
- if (ioctl_or_warn(fd, SIOCGIFINDEX, ifr) != 0) {
- close(fd);
- return -1;
- }
- log1("adapter index %d", ifr->ifr_ifindex);
- *ifindex = ifr->ifr_ifindex;
- }
-
- if (mac) {
- if (ioctl_or_warn(fd, SIOCGIFHWADDR, ifr) != 0) {
- close(fd);
- return -1;
- }
- memcpy(mac, ifr->ifr_hwaddr.sa_data, 6);
- log1("MAC %02x:%02x:%02x:%02x:%02x:%02x",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
- }
-
- close(fd);
- return 0;
+int FAST_FUNC udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, struct in6_addr **nip6, uint8_t *mac) {
+ struct ifaddrs *ifap, *ifa;
+
+ getifaddrs (&ifap);
+
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if (!ifa->ifa_addr || (strcmp (ifa->ifa_name, interface) != 0))
+ continue;
+
+ if (ifa->ifa_addr->sa_family == AF_PACKET) {
+ if (mac) {
+ memcpy (mac, ((struct sockaddr_ll *)ifa->ifa_addr)->sll_addr, 6);
+ log1 ("MAC %02x:%02x:%02x:%02x:%02x:%02x", mac [0], mac [1], mac [2], mac [3], mac [4], mac [5]);
+ }
+
+ if (ifindex) {
+ log1 ("adapter index %d", ((struct sockaddr_ll *)ifa->ifa_addr)->sll_ifindex);
+ *ifindex = ((struct sockaddr_ll *)ifa->ifa_addr)->sll_ifindex;
+ }
+ } else if (nip && (ifa->ifa_addr->sa_family == AF_INET)) {
+ *nip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
+ log1 ("IP %s", inet_ntoa (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr));
+
+ } else if (nip6 && (ifa->ifa_addr->sa_family == AF_INET6) && IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
+ *nip6 = malloc (sizeof (struct in6_addr));
+ memcpy (*nip6, &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, sizeof (struct in6_addr));
+ log1 (
+ "IPv6 %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+ (*nip6)->s6_addr [0], (*nip6)->s6_addr [1],
+ (*nip6)->s6_addr [2], (*nip6)->s6_addr [3],
+ (*nip6)->s6_addr [4], (*nip6)->s6_addr [5],
+ (*nip6)->s6_addr [6], (*nip6)->s6_addr [7],
+ (*nip6)->s6_addr [8], (*nip6)->s6_addr [9],
+ (*nip6)->s6_addr [10], (*nip6)->s6_addr [11],
+ (*nip6)->s6_addr [12], (*nip6)->s6_addr [13],
+ (*nip6)->s6_addr [14], (*nip6)->s6_addr [15]
+ );
+ }
+ }
+
+ freeifaddrs (ifap);
+
+ return 0;
}
/* 1. None of the callers expects it to ever fail */
diff -Nru busybox-1.26.2.org/networking/udhcp/d6_common.h busybox-1.26.2.mod/networking/udhcp/d6_common.h
--- busybox-1.26.2.org/networking/udhcp/d6_common.h 2016-09-27 18:53:50.000000000 +0200
+++ busybox-1.26.2.mod/networking/udhcp/d6_common.h 2017-03-06 20:14:11.636939559 +0100
@@ -81,9 +81,14 @@
#define D6_OPT_RECONF_MSG 19
#define D6_OPT_RECONF_ACCEPT 20
+#define D6_OPT_DNS_SERVERS 23
+#define D6_OPT_DOMAIN_LIST 24
+
#define D6_OPT_IA_PD 25
#define D6_OPT_IAPREFIX 26
+#define D6_OPT_CLIENT_FQDN 39
+
/*** Other shared functions ***/
struct client6_data_t {
diff -Nru busybox-1.26.2.org/networking/udhcp/d6_dhcpc.c busybox-1.26.2.mod/networking/udhcp/d6_dhcpc.c
--- busybox-1.26.2.org/networking/udhcp/d6_dhcpc.c 2016-09-27 18:53:50.000000000 +0200
+++ busybox-1.26.2.mod/networking/udhcp/d6_dhcpc.c 2017-03-06 20:16:58.441939869 +0100
@@ -86,6 +86,19 @@
IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,)
};
+const char opt_req[] = {
+ (D6_OPT_ORO >> 8), (D6_OPT_ORO & 0xFF),
+ 0, 6,
+ (D6_OPT_DNS_SERVERS >> 8), (D6_OPT_DNS_SERVERS & 0xFF),
+ (D6_OPT_DOMAIN_LIST >> 8), (D6_OPT_DOMAIN_LIST & 0xFF),
+ (D6_OPT_CLIENT_FQDN >> 8), (D6_OPT_CLIENT_FQDN & 0xFF)
+};
+
+const char opt_fqdn_req[] = {
+ (D6_OPT_CLIENT_FQDN >> 8), (D6_OPT_CLIENT_FQDN & 0xFF),
+ 0, 2,
+ 0, 0
+};
/*** Utility functions ***/
@@ -107,8 +120,8 @@
/* Does its code match? */
if (option[1] == code)
return option; /* yes! */
- option += option[3] + 4;
len_m4 -= option[3] + 4;
+ option += option[3] + 4;
}
return NULL;
}
@@ -140,14 +153,16 @@
static void option_to_env(uint8_t *option, uint8_t *option_end)
{
/* "length minus 4" */
+ char *dlist, *ptr;
int len_m4 = option_end - option - 4;
+ int olen, ooff;
while (len_m4 >= 0) {
uint32_t v32;
char ipv6str[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")];
if (option[0] != 0 || option[2] != 0)
break;
-
+
switch (option[1]) {
//case D6_OPT_CLIENTID:
//case D6_OPT_SERVERID:
@@ -217,9 +232,55 @@
sprint_nip6(ipv6str, option + 4 + 4 + 1);
*new_env() = xasprintf("ipv6prefix=%s/%u", ipv6str, (unsigned)(option[4 + 4]));
+ break;
+ case D6_OPT_DNS_SERVERS:
+ olen = ((option [2] << 8) | option [3]) / 16;
+ dlist = ptr = malloc (4 + olen * 40 - 1);
+
+ memcpy (ptr, "dns=", 4);
+ ptr += 4;
+ ooff = 0;
+
+ while (olen--) {
+ sprint_nip6 (ptr, option + 4 + ooff);
+
+ ptr += 39;
+ ooff += 16;
+
+ if (olen) *ptr++ = ' ';
+ }
+
+ *new_env() = dlist;
+
+ break;
+ case D6_OPT_DOMAIN_LIST:
+ if (!(dlist = dname_dec (option + 4, (option [2] << 8) | option [3], "search=")))
+ break;
+
+ *new_env() = dlist;
+
+ break;
+ case D6_OPT_CLIENT_FQDN:
+ // Work around broken ISC DHCPD6
+ if (option [4] & 0xF8) {
+ olen = ((option [2] << 8) | option [3]);
+ dlist = malloc (olen);
+ memcpy (dlist, option + 4, olen);
+ *new_env() = xasprintf("fqdn=%s", dlist);
+ free (dlist);
+
+ break;
+ }
+
+ if (!(dlist = dname_dec (option + 5, ((option [2] << 8) | option [3]) - 1, "fqdn=")))
+ break;
+
+ *new_env() = dlist;
+
+ break;
}
- option += 4 + option[3];
len_m4 -= 4 + option[3];
+ option += 4 + option[3];
}
}
@@ -422,7 +483,11 @@
memcpy(iaaddr->data, requested_ipv6, 16);
}
opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, len);
-
+
+ /* Request additional options */
+ opt_ptr = d6_store_blob (opt_ptr, &opt_req, sizeof (opt_req));
+ opt_ptr = d6_store_blob (opt_ptr, &opt_fqdn_req, sizeof (opt_fqdn_req));
+
/* Add options:
* "param req" option according to -O, options specified with -x
*/
@@ -475,7 +540,11 @@
opt_ptr = d6_store_blob(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2);
/* IA NA (contains requested IP) */
opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, client6_data.ia_na->len + 2+2);
-
+
+ /* Request additional options */
+ opt_ptr = d6_store_blob (opt_ptr, &opt_req, sizeof (opt_req));
+ opt_ptr = d6_store_blob (opt_ptr, &opt_fqdn_req, sizeof (opt_fqdn_req));
+
/* Add options:
* "param req" option according to -O, options specified with -x
*/
@@ -1307,7 +1381,7 @@
struct d6_option *option, *iaaddr;
type_is_ok:
option = d6_find_option(packet.d6_options, packet_end, D6_OPT_STATUS_CODE);
- if (option && option->data[4] != 0) {
+ if (option && (((option->data [0] << 8) | option->data [1]) != 0)) {
/* return to init state */
bb_error_msg("received DHCP NAK (%u)", option->data[4]);
d6_run_script(&packet, "nak");
diff -Nru busybox-1.26.2.org/networking/udhcp/d6_common.h busybox-1.26.2.mod/networking/udhcp/d6_common.h
--- busybox-1.26.2.org/networking/udhcp/d6_common.h 2016-09-27 18:53:50.000000000 +0200
+++ busybox-1.26.2.mod/networking/udhcp/d6_common.h 2017-03-06 20:14:11.636939559 +0100
@@ -112,7 +118,8 @@
int FAST_FUNC d6_send_kernel_packet(
struct d6_packet *d6_pkt, unsigned d6_pkt_size,
struct in6_addr *src_ipv6, int source_port,
- struct in6_addr *dst_ipv6, int dest_port
+ struct in6_addr *dst_ipv6, int dest_port,
+ int ifindex
);
#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2
diff -Nru busybox-1.26.2.org/networking/udhcp/d6_dhcpc.c busybox-1.26.2.mod/networking/udhcp/d6_dhcpc.c
--- busybox-1.26.2.org/networking/udhcp/d6_dhcpc.c 2016-09-27 18:53:50.000000000 +0200
+++ busybox-1.26.2.mod/networking/udhcp/d6_dhcpc.c 2017-03-06 20:16:58.441939869 +0100
@@ -555,7 +624,8 @@
return d6_send_kernel_packet(
&packet, (opt_ptr - (uint8_t*) &packet),
our_cur_ipv6, CLIENT_PORT6,
- server_ipv6, SERVER_PORT6
+ server_ipv6, SERVER_PORT6,
+ client_config.ifindex
);
return d6_mcast_from_client_config_ifindex(&packet, opt_ptr);
}
@@ -577,16 +647,14 @@
return d6_send_kernel_packet(
&packet, (opt_ptr - (uint8_t*) &packet),
our_cur_ipv6, CLIENT_PORT6,
- server_ipv6, SERVER_PORT6
+ server_ipv6, SERVER_PORT6,
+ client_config.ifindex
);
}
/* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */
/* NOINLINE: limit stack usage in caller */
-static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6
- UNUSED_PARAM
- , struct d6_packet *d6_pkt, int fd)
-{
+static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6, struct d6_packet *d6_pkt, int fd) {
int bytes;
struct ip6_udp_d6_packet packet;
@@ -634,6 +702,9 @@
// return -2;
// }
+ if (peer_ipv6)
+ memcpy (peer_ipv6, &packet.ip6.ip6_src, sizeof (struct in6_addr));
+
log1("received %s", "a packet");
d6_dump_packet(&packet.data);
diff -Nru busybox-1.26.2.org/networking/udhcp/d6_packet.c busybox-1.26.2.mod/networking/udhcp/d6_packet.c
--- busybox-1.26.2.org/networking/udhcp/d6_packet.c 2016-09-27 18:53:50.000000000 +0200
+++ busybox-1.26.2.mod/networking/udhcp/d6_packet.c 2017-03-06 20:17:19.038063287 +0100
@@ -127,7 +127,8 @@
int FAST_FUNC d6_send_kernel_packet(
struct d6_packet *d6_pkt, unsigned d6_pkt_size,
struct in6_addr *src_ipv6, int source_port,
- struct in6_addr *dst_ipv6, int dest_port)
+ struct in6_addr *dst_ipv6, int dest_port,
+ int ifindex)
{
struct sockaddr_in6 sa;
int fd;
@@ -140,7 +141,7 @@
goto ret_msg;
}
setsockopt_reuseaddr(fd);
-
+
memset(&sa, 0, sizeof(sa));
sa.sin6_family = AF_INET6;
sa.sin6_port = htons(source_port);
@@ -154,6 +155,7 @@
sa.sin6_family = AF_INET6;
sa.sin6_port = htons(dest_port);
sa.sin6_addr = *dst_ipv6; /* struct copy */
+ sa.sin6_scope_id = ifindex;
if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
msg = "connect";
goto ret_close;
smime.p7s
Description: S/MIME Cryptographic Signature
_______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
