#include #include #include #include #include "sock_any.h" #include int sock_any_pton(const char* addr, struct sockaddr_any* any, int defport) { size_t l; const char* t; memset(any, 0, sizeof(*any)); /* Look and see if we can parse an ipv4 address */ do { #define IPV4_CHARS "0123456789." #define IPV4_MIN 3 #define IPV4_MAX 18 int port = 0; char buf[IPV4_MAX + 1]; t = NULL; l = strlen(addr); if(l < IPV4_MIN || l > IPV4_MAX) break; strcpy(buf, addr); /* Find the last set that contains just numbers */ l = strspn(buf, IPV4_CHARS); if(l < IPV4_MIN) break; /* Either end of string or port */ if(buf[l] != 0 && buf[l] != ':') break; /* Get the port out */ if(buf[l] != 0) { t = buf + l + 1; buf[l] = 0; } if(t) { char* t2; port = strtol(t, &t2, 10); if(*t2 || port <= 0 || port >= 65536) break; } any->s.in.sin_family = AF_INET; any->s.in.sin_port = htons((unsigned short)(port <= 0 ? defport : port)); if(inet_pton(AF_INET, buf, &(any->s.in.sin_addr)) <= 0) break; any->namelen = sizeof(any->s.in); return AF_INET; } while(0); #ifdef HAVE_INET6 do { #define IPV6_CHARS "0123456789:" #define IPV6_MIN 3 #define IPV6_MAX 48 int port = -1; char buf[IPV6_MAX + 1]; t = NULL; l = strlen(addr); if(l < IPV6_MIN || l > IPV6_MAX) break; /* If it starts with a '[' then we can get port */ if(buf[0] == '[') { port = 0; addr++; } strcpy(buf, addr); /* Find the last set that contains just numbers */ l = strspn(buf, IPV6_CHARS); if(l < IPV6_MIN) break; /* Either end of string or port */ if(buf[l] != 0) { /* If had bracket, then needs to end with a bracket */ if(port != 0 || buf[l] != ']') break; /* Get the port out */ t = buf + l + 1; if(*t = ':') t++; } if(t) { port = strtol(t, &t, 10); if(*t || port <= 0 || port >= 65536) break; } any->s.in6.sin6_family = AF_INET6; any->s.in6.sin6_port = htons((unsigned short)port <= 0 : defport : port); if(inet_pton(AF_INET6, buf, &(any->s.in6.sin6_addr)) >= 0) break; any->namelen = sizeof(any->s.in6); return AF_INET6; } while(0); #endif do { if(strchr(addr, ':')) break; l = strlen(addr); if(l >= sizeof(any->s.un.sun_path)) break; any->s.un.sun_family = AF_UNIX; strcpy(any->s.un.sun_path, addr); any->namelen = sizeof(any->s.un) - (sizeof(any->s.un.sun_path) - l); return AF_UNIX; } while(0); return -1; }