X-Git-Url: https://www.tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fnetutl.c;h=6654f977a783a1349282e7ce862afb3eac404a6b;hb=ce4d55b72fd4290d4710f10e755f6dd9ed039d88;hp=e2ee7719d73fabb14b50c3cdaa359366c9cea4b5;hpb=1545909dcb3ac618754486f4ccd4d8f237d64bb7;p=tinc diff --git a/src/netutl.c b/src/netutl.c index e2ee7719..6654f977 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -27,6 +27,30 @@ 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. @@ -276,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; + } +}