Use actual port in tincd logs / tinc get Port / invitations
[tinc] / src / netutl.c
index 4e58911..0c19f5b 100644 (file)
 #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;
@@ -277,3 +300,20 @@ void sockaddr_setport(sockaddr_t *sa, const char *port) {
                return;
        }
 }
+
+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;
+       }
+}