aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-06-05 20:08:11 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-06-05 20:08:11 +0000
commit5c51a7ca52beb6958fda45f0de480f6ac1769ec6 (patch)
tree55bc26e011712115ecdfcb01588f9f65f6397462
parent6c501a71ae50fa8f788bbc46511e8c4071e5f897 (diff)
downloadbusybox-w32-5c51a7ca52beb6958fda45f0de480f6ac1769ec6.tar.gz
busybox-w32-5c51a7ca52beb6958fda45f0de480f6ac1769ec6.tar.bz2
busybox-w32-5c51a7ca52beb6958fda45f0de480f6ac1769ec6.zip
nc: make connecting to IPv4 from IPv6-enabled hosts easier
(was requiring -s <local addr>)
-rw-r--r--include/libbb.h9
-rw-r--r--libbb/xconnect.c32
-rw-r--r--networking/nc_bloaty.c21
3 files changed, 38 insertions, 24 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 013633716..dd0f5c1cc 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -304,9 +304,12 @@ enum {
304 } 304 }
305 ) 305 )
306}; 306};
307/* Create stream socket, and allocated suitable lsa 307/* Create stream socket, and allocate suitable lsa.
308 * (lsa of correct size and lsa->sa.sa_family (AF_INET/AF_INET6)) */ 308 * (lsa of correct size and lsa->sa.sa_family (AF_INET/AF_INET6))
309int xsocket_type(len_and_sockaddr **lsap, int sock_type); 309 * af == AF_UNSPEC will result in trying to create IPv6, and
310 * if kernel doesn't support it, IPv4.
311 */
312int xsocket_type(len_and_sockaddr **lsap, USE_FEATURE_IPV6(int af,) int sock_type);
310int xsocket_stream(len_and_sockaddr **lsap); 313int xsocket_stream(len_and_sockaddr **lsap);
311/* Create server socket bound to bindaddr:port. bindaddr can be NULL, 314/* Create server socket bound to bindaddr:port. bindaddr can be NULL,
312 * numeric IP ("N.N.N.N") or numeric IPv6 address, 315 * numeric IP ("N.N.N.N") or numeric IPv6 address,
diff --git a/libbb/xconnect.c b/libbb/xconnect.c
index e7d510678..b90aa9add 100644
--- a/libbb/xconnect.c
+++ b/libbb/xconnect.c
@@ -208,23 +208,31 @@ len_and_sockaddr* xdotted2sockaddr(const char *host, int port)
208 return str2sockaddr(host, port, AF_UNSPEC, AI_NUMERICHOST | DIE_ON_ERROR); 208 return str2sockaddr(host, port, AF_UNSPEC, AI_NUMERICHOST | DIE_ON_ERROR);
209} 209}
210 210
211int xsocket_type(len_and_sockaddr **lsap, int sock_type) 211int xsocket_type(len_and_sockaddr **lsap, USE_FEATURE_IPV6(int family,) int sock_type)
212{ 212{
213 SKIP_FEATURE_IPV6(enum { family = AF_INET };)
213 len_and_sockaddr *lsa; 214 len_and_sockaddr *lsa;
214 int fd; 215 int fd;
215 int len = sizeof(struct sockaddr_in); 216 int len;
216 int family = AF_INET;
217 217
218#if ENABLE_FEATURE_IPV6 218#if ENABLE_FEATURE_IPV6
219 fd = socket(AF_INET6, sock_type, 0); 219 if (family == AF_UNSPEC) {
220 if (fd >= 0) { 220 fd = socket(AF_INET6, sock_type, 0);
221 len = sizeof(struct sockaddr_in6); 221 if (fd >= 0) {
222 family = AF_INET6; 222 family = AF_INET6;
223 } else 223 goto done;
224 }
225 family = AF_INET;
226 }
224#endif 227#endif
225 { 228 fd = xsocket(family, sock_type, 0);
226 fd = xsocket(AF_INET, sock_type, 0); 229 len = sizeof(struct sockaddr_in);
230#if ENABLE_FEATURE_IPV6
231 if (family == AF_INET6) {
232 done:
233 len = sizeof(struct sockaddr_in6);
227 } 234 }
235#endif
228 lsa = xzalloc(offsetof(len_and_sockaddr, sa) + len); 236 lsa = xzalloc(offsetof(len_and_sockaddr, sa) + len);
229 lsa->len = len; 237 lsa->len = len;
230 lsa->sa.sa_family = family; 238 lsa->sa.sa_family = family;
@@ -234,7 +242,7 @@ int xsocket_type(len_and_sockaddr **lsap, int sock_type)
234 242
235int xsocket_stream(len_and_sockaddr **lsap) 243int xsocket_stream(len_and_sockaddr **lsap)
236{ 244{
237 return xsocket_type(lsap, SOCK_STREAM); 245 return xsocket_type(lsap, USE_FEATURE_IPV6(AF_UNSPEC,) SOCK_STREAM);
238} 246}
239 247
240static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type) 248static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type)
@@ -247,7 +255,7 @@ static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type)
247 /* user specified bind addr dictates family */ 255 /* user specified bind addr dictates family */
248 fd = xsocket(lsa->sa.sa_family, sock_type, 0); 256 fd = xsocket(lsa->sa.sa_family, sock_type, 0);
249 } else { 257 } else {
250 fd = xsocket_type(&lsa, sock_type); 258 fd = xsocket_type(&lsa, USE_FEATURE_IPV6(AF_UNSPEC,) sock_type);
251 set_nport(lsa, htons(port)); 259 set_nport(lsa, htons(port));
252 } 260 }
253 setsockopt_reuseaddr(fd); 261 setsockopt_reuseaddr(fd);
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c
index 5096e3227..a318c8126 100644
--- a/networking/nc_bloaty.c
+++ b/networking/nc_bloaty.c
@@ -751,6 +751,13 @@ int nc_main(int argc, char **argv)
751 /* We manage our fd's so that they are never 0,1,2 */ 751 /* We manage our fd's so that they are never 0,1,2 */
752 /*bb_sanitize_stdio(); - not needed */ 752 /*bb_sanitize_stdio(); - not needed */
753 753
754 if (argv[0]) {
755 themaddr = xhost2sockaddr(argv[0],
756 argv[1]
757 ? bb_lookup_port(argv[1], o_udpmode ? "udp" : "tcp", 0)
758 : 0);
759 }
760
754 /* create & bind network socket */ 761 /* create & bind network socket */
755 x = (o_udpmode ? SOCK_DGRAM : SOCK_STREAM); 762 x = (o_udpmode ? SOCK_DGRAM : SOCK_STREAM);
756 if (option_mask32 & OPT_s) { /* local address */ 763 if (option_mask32 & OPT_s) { /* local address */
@@ -758,7 +765,11 @@ int nc_main(int argc, char **argv)
758 ouraddr = xhost2sockaddr(str_s, o_lport); 765 ouraddr = xhost2sockaddr(str_s, o_lport);
759 x = xsocket(ouraddr->sa.sa_family, x, 0); 766 x = xsocket(ouraddr->sa.sa_family, x, 0);
760 } else { 767 } else {
761 x = xsocket_type(&ouraddr, x); 768 /* We try IPv6, then IPv4, unless addr family is
769 * implicitly set by way of remote addr/port spec */
770 x = xsocket_type(&ouraddr,
771 USE_FEATURE_IPV6((themaddr ? themaddr->sa.sa_family : AF_UNSPEC),)
772 x);
762 if (o_lport) 773 if (o_lport)
763 set_nport(ouraddr, htons(o_lport)); 774 set_nport(ouraddr, htons(o_lport));
764 } 775 }
@@ -789,14 +800,6 @@ int nc_main(int argc, char **argv)
789 xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), ofd); 800 xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), ofd);
790#endif 801#endif
791 802
792 if (argv[0]) {
793 themaddr = xhost2sockaddr(argv[0],
794 argv[1]
795 ? bb_lookup_port(argv[1], o_udpmode ? "udp" : "tcp", 0)
796 : 0);
797///what if sa_family won't match??
798 }
799
800 if (o_listen) { 803 if (o_listen) {
801 dolisten(); 804 dolisten();
802 /* dolisten does its own connect reporting */ 805 /* dolisten does its own connect reporting */