X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libbb%2Fxconnect.c;h=65554b24e177140e085f852c50d80123fb29229f;hb=21b080daa8c180a43d10d6b3dee47134ef21e581;hp=a5b16d982ae4a27b6c5ba733e20a3f34f95d000a;hpb=8e9ccba371480fb1fb3da9235fabdbb7861523c3;p=oweals%2Fbusybox.git diff --git a/libbb/xconnect.c b/libbb/xconnect.c index a5b16d982..65554b24e 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c @@ -32,13 +32,13 @@ void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) } } -/* Return network byte ordered port number for a service. +/* Return port number for a service. * If "port" is a number use it as the port. * If "port" is a name it is looked up in /etc/services, if it isnt found return * default_port */ unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port) { - unsigned port_nr = htons(default_port); + unsigned port_nr = default_port; if (port) { int old_errno; @@ -49,13 +49,11 @@ unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default if (errno || port_nr > 65535) { struct servent *tserv = getservbyname(port, protocol); if (tserv) - port_nr = tserv->s_port; - } else { - port_nr = htons(port_nr); + port_nr = ntohs(tserv->s_port); } errno = old_errno; } - return port_nr; + return (uint16_t)port_nr; } @@ -83,7 +81,21 @@ int xconnect_tcp_v4(struct sockaddr_in *s_addr) /* "New" networking API */ -void set_port(len_and_sockaddr *lsa, unsigned port) +int get_nport(len_and_sockaddr *lsa) +{ +#if ENABLE_FEATURE_IPV6 + if (lsa->sa.sa_family == AF_INET6) { + return lsa->sin6.sin6_port; + } +#endif + if (lsa->sa.sa_family == AF_INET) { + return lsa->sin.sin_port; + } + return -1; + /* What? UNIX socket? IPX?? :) */ +} + +void set_nport(len_and_sockaddr *lsa, unsigned port) { #if ENABLE_FEATURE_IPV6 if (lsa->sa.sa_family == AF_INET6) { @@ -148,7 +160,7 @@ static len_and_sockaddr* str2sockaddr(const char *host, int port, int ai_flags) r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); r->len = result->ai_addrlen; memcpy(&r->sa, result->ai_addr, result->ai_addrlen); - set_port(r, port); + set_nport(r, htons(port)); freeaddrinfo(result); return r; } @@ -163,19 +175,27 @@ static len_and_sockaddr* dotted2sockaddr(const char *host, int port) return str2sockaddr(host, port, NI_NUMERICHOST); } -static int xsocket_stream(len_and_sockaddr *lsa) +int xsocket_stream(len_and_sockaddr **lsap) { + len_and_sockaddr *lsa; int fd; + int len = sizeof(struct sockaddr_in); + int family = AF_INET; + #if ENABLE_FEATURE_IPV6 fd = socket(AF_INET6, SOCK_STREAM, 0); - lsa->sa.sa_family = AF_INET6; - lsa->len = sizeof(struct sockaddr_in6); - if (fd >= 0) - return fd; + if (fd >= 0) { + len = sizeof(struct sockaddr_in6); + family = AF_INET6; + } else #endif - fd = xsocket(AF_INET, SOCK_STREAM, 0); - lsa->sa.sa_family = AF_INET; - lsa->len = sizeof(struct sockaddr_in); + { + fd = xsocket(AF_INET, SOCK_STREAM, 0); + } + lsa = xzalloc(offsetof(len_and_sockaddr, sa) + len); + lsa->len = len; + lsa->sa.sa_family = family; + *lsap = lsa; return fd; } @@ -192,11 +212,7 @@ int create_and_bind_stream_or_die(const char *bindaddr, int port) /* user specified bind addr dictates family */ fd = xsocket(lsa->sa.sa_family, SOCK_STREAM, 0); } else { - lsa = xzalloc(offsetof(len_and_sockaddr, sa) + - USE_FEATURE_IPV6(sizeof(struct sockaddr_in6)) - SKIP_FEATURE_IPV6(sizeof(struct sockaddr_in)) - ); - fd = xsocket_stream(lsa); + fd = xsocket_stream(&lsa); } setsockopt_reuseaddr(fd); xbind(fd, &lsa->sa, lsa->len); @@ -237,6 +253,7 @@ static char* sockaddr2str(const struct sockaddr *sa, socklen_t salen, int flags) flags | NI_NUMERICSERV /* do not resolve port# */ ); if (rc) return NULL; +// We probably need to use [%s]:%s for IPv6... return xasprintf("%s:%s", host, serv); }