X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fnetutl.c;h=6654f977a783a1349282e7ce862afb3eac404a6b;hb=28be4baae016a5a771d0d9ec6e97ef38a4fc9e46;hp=73719232bb4cce6c05b605c837e3d00e9f0323bb;hpb=f6e87ab476a0faf8b124ecaaa27f967d825e6457;p=tinc diff --git a/src/netutl.c b/src/netutl.c index 73719232..6654f977 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -23,11 +23,34 @@ #include "net.h" #include "netutl.h" #include "logger.h" -#include "utils.h" #include "xalloc.h" bool hostnames = false; +uint16_t service_to_port(const char *service) { + struct addrinfo *ai = str2addrinfo("localhost", service, SOCK_STREAM); + + if(!ai || !ai->ai_addr) { + return 0; + } + + sockaddr_t sa; + memcpy(&sa, ai->ai_addr, ai->ai_addrlen); + freeaddrinfo(ai); + + switch(sa.sa.sa_family) { + case AF_INET: + return ntohs(sa.in.sin_port); + + case AF_INET6: + return ntohs(sa.in6.sin6_port); + + default: + logger(DEBUG_ALWAYS, LOG_WARNING, "Unknown address family %d for service %s.", sa.sa.sa_family, service); + return 0; + } +} + /* Turn a string into a struct addrinfo. Return NULL on failure. @@ -54,7 +77,7 @@ struct addrinfo *str2addrinfo(const char *address, const char *service, int sock sockaddr_t str2sockaddr(const char *address, const char *port) { struct addrinfo *ai, hint = {0}; - sockaddr_t result = {{0}}; + sockaddr_t result = {0}; int err; hint.ai_family = AF_UNSPEC; @@ -105,7 +128,7 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) { return; } - err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof port, NI_NUMERICHOST | NI_NUMERICSERV); + err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); if(err) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while translating addresses: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err)); @@ -141,7 +164,7 @@ char *sockaddr2hostname(const sockaddr_t *sa) { return str; } - err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof port, + err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), hostnames ? 0 : (NI_NUMERICHOST | NI_NUMERICSERV)); if(err) { @@ -277,3 +300,37 @@ void sockaddr_setport(sockaddr_t *sa, const char *port) { return; } } + +bool is_local_connection(const sockaddr_t *sa) { + switch(sa->sa.sa_family) { + case AF_INET: + // 127.0.0.0/8 + return ntohl(sa->in.sin_addr.s_addr) >> 24 == 127; + + case AF_INET6: + return IN6_IS_ADDR_LOOPBACK(&sa->in6.sin6_addr); + + case AF_UNIX: + return true; + + default: + return false; + } +} + +uint16_t get_bound_port(int sockfd) { + sockaddr_t sa; + socklen_t salen = sizeof(sa); + + if(getsockname(sockfd, (struct sockaddr *) &sa, &salen)) { + return 0; + } + + if(sa.sa.sa_family == AF_INET) { + return ntohs(sa.in.sin_port); + } else if(sa.sa.sa_family == AF_INET6) { + return ntohs(sa.in6.sin6_port); + } else { + return 0; + } +}