diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-12 20:59:31 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-12 20:59:31 +0000 |
| commit | 5d68724d5b89fbf2856fdfbf36b85ac36a8f4464 (patch) | |
| tree | 755b7393aab965f03de260a833f77cc4d51e6187 /libbb | |
| parent | 2c91652bbcc82c794c26230806058b04f1711033 (diff) | |
| download | busybox-w32-5d68724d5b89fbf2856fdfbf36b85ac36a8f4464.tar.gz busybox-w32-5d68724d5b89fbf2856fdfbf36b85ac36a8f4464.tar.bz2 busybox-w32-5d68724d5b89fbf2856fdfbf36b85ac36a8f4464.zip | |
next part of ipv6-ization. mostly netcat.
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/xconnect.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index f5a7e6dc8..65554b24e 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
| @@ -32,7 +32,7 @@ void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) | |||
| 32 | } | 32 | } |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | /* Return network byte ordered port number for a service. | 35 | /* Return port number for a service. |
| 36 | * If "port" is a number use it as the port. | 36 | * If "port" is a number use it as the port. |
| 37 | * If "port" is a name it is looked up in /etc/services, if it isnt found return | 37 | * If "port" is a name it is looked up in /etc/services, if it isnt found return |
| 38 | * default_port */ | 38 | * default_port */ |
| @@ -81,7 +81,21 @@ int xconnect_tcp_v4(struct sockaddr_in *s_addr) | |||
| 81 | /* "New" networking API */ | 81 | /* "New" networking API */ |
| 82 | 82 | ||
| 83 | 83 | ||
| 84 | void set_port(len_and_sockaddr *lsa, unsigned port) | 84 | int get_nport(len_and_sockaddr *lsa) |
| 85 | { | ||
| 86 | #if ENABLE_FEATURE_IPV6 | ||
| 87 | if (lsa->sa.sa_family == AF_INET6) { | ||
| 88 | return lsa->sin6.sin6_port; | ||
| 89 | } | ||
| 90 | #endif | ||
| 91 | if (lsa->sa.sa_family == AF_INET) { | ||
| 92 | return lsa->sin.sin_port; | ||
| 93 | } | ||
| 94 | return -1; | ||
| 95 | /* What? UNIX socket? IPX?? :) */ | ||
| 96 | } | ||
| 97 | |||
| 98 | void set_nport(len_and_sockaddr *lsa, unsigned port) | ||
| 85 | { | 99 | { |
| 86 | #if ENABLE_FEATURE_IPV6 | 100 | #if ENABLE_FEATURE_IPV6 |
| 87 | if (lsa->sa.sa_family == AF_INET6) { | 101 | if (lsa->sa.sa_family == AF_INET6) { |
| @@ -146,7 +160,7 @@ static len_and_sockaddr* str2sockaddr(const char *host, int port, int ai_flags) | |||
| 146 | r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); | 160 | r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); |
| 147 | r->len = result->ai_addrlen; | 161 | r->len = result->ai_addrlen; |
| 148 | memcpy(&r->sa, result->ai_addr, result->ai_addrlen); | 162 | memcpy(&r->sa, result->ai_addr, result->ai_addrlen); |
| 149 | set_port(r, htons(port)); | 163 | set_nport(r, htons(port)); |
| 150 | freeaddrinfo(result); | 164 | freeaddrinfo(result); |
| 151 | return r; | 165 | return r; |
| 152 | } | 166 | } |
| @@ -161,19 +175,27 @@ static len_and_sockaddr* dotted2sockaddr(const char *host, int port) | |||
| 161 | return str2sockaddr(host, port, NI_NUMERICHOST); | 175 | return str2sockaddr(host, port, NI_NUMERICHOST); |
| 162 | } | 176 | } |
| 163 | 177 | ||
| 164 | static int xsocket_stream(len_and_sockaddr *lsa) | 178 | int xsocket_stream(len_and_sockaddr **lsap) |
| 165 | { | 179 | { |
| 180 | len_and_sockaddr *lsa; | ||
| 166 | int fd; | 181 | int fd; |
| 182 | int len = sizeof(struct sockaddr_in); | ||
| 183 | int family = AF_INET; | ||
| 184 | |||
| 167 | #if ENABLE_FEATURE_IPV6 | 185 | #if ENABLE_FEATURE_IPV6 |
| 168 | fd = socket(AF_INET6, SOCK_STREAM, 0); | 186 | fd = socket(AF_INET6, SOCK_STREAM, 0); |
| 169 | lsa->sa.sa_family = AF_INET6; | 187 | if (fd >= 0) { |
| 170 | lsa->len = sizeof(struct sockaddr_in6); | 188 | len = sizeof(struct sockaddr_in6); |
| 171 | if (fd >= 0) | 189 | family = AF_INET6; |
| 172 | return fd; | 190 | } else |
| 173 | #endif | 191 | #endif |
| 174 | fd = xsocket(AF_INET, SOCK_STREAM, 0); | 192 | { |
| 175 | lsa->sa.sa_family = AF_INET; | 193 | fd = xsocket(AF_INET, SOCK_STREAM, 0); |
| 176 | lsa->len = sizeof(struct sockaddr_in); | 194 | } |
| 195 | lsa = xzalloc(offsetof(len_and_sockaddr, sa) + len); | ||
| 196 | lsa->len = len; | ||
| 197 | lsa->sa.sa_family = family; | ||
| 198 | *lsap = lsa; | ||
| 177 | return fd; | 199 | return fd; |
| 178 | } | 200 | } |
| 179 | 201 | ||
| @@ -190,11 +212,7 @@ int create_and_bind_stream_or_die(const char *bindaddr, int port) | |||
| 190 | /* user specified bind addr dictates family */ | 212 | /* user specified bind addr dictates family */ |
| 191 | fd = xsocket(lsa->sa.sa_family, SOCK_STREAM, 0); | 213 | fd = xsocket(lsa->sa.sa_family, SOCK_STREAM, 0); |
| 192 | } else { | 214 | } else { |
| 193 | lsa = xzalloc(offsetof(len_and_sockaddr, sa) + | 215 | fd = xsocket_stream(&lsa); |
| 194 | USE_FEATURE_IPV6(sizeof(struct sockaddr_in6)) | ||
| 195 | SKIP_FEATURE_IPV6(sizeof(struct sockaddr_in)) | ||
| 196 | ); | ||
| 197 | fd = xsocket_stream(lsa); | ||
| 198 | } | 216 | } |
| 199 | setsockopt_reuseaddr(fd); | 217 | setsockopt_reuseaddr(fd); |
| 200 | xbind(fd, &lsa->sa, lsa->len); | 218 | xbind(fd, &lsa->sa, lsa->len); |
