diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-05 20:08:11 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-05 20:08:11 +0000 |
commit | 5c51a7ca52beb6958fda45f0de480f6ac1769ec6 (patch) | |
tree | 55bc26e011712115ecdfcb01588f9f65f6397462 /libbb | |
parent | 6c501a71ae50fa8f788bbc46511e8c4071e5f897 (diff) | |
download | busybox-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>)
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/xconnect.c | 32 |
1 files changed, 20 insertions, 12 deletions
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 | ||
211 | int xsocket_type(len_and_sockaddr **lsap, int sock_type) | 211 | int 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 | ||
235 | int xsocket_stream(len_and_sockaddr **lsap) | 243 | int 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 | ||
240 | static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type) | 248 | static 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); |