diff options
-rw-r--r-- | src/libstrongswan/networking/host.c | 72 | ||||
-rw-r--r-- | src/libstrongswan/networking/host.h | 11 |
2 files changed, 48 insertions, 35 deletions
diff --git a/src/libstrongswan/networking/host.c b/src/libstrongswan/networking/host.c index 66a8ff1f5..160a6ec1b 100644 --- a/src/libstrongswan/networking/host.c +++ b/src/libstrongswan/networking/host.c @@ -358,57 +358,59 @@ static host_t *host_create_any_port(int family, u_int16_t port) /* * Described in header. */ -host_t *host_create_from_string(char *string, u_int16_t port) +host_t *host_create_from_string_and_family(char *string, int family, + u_int16_t port) { - private_host_t *this; + union { + sockaddr_t sockaddr; + struct sockaddr_in v4; + struct sockaddr_in6 v6; + } addr; - if (streq(string, "%any")) + if ((family == AF_UNSPEC || family == AF_INET) && streq(string, "%any")) { return host_create_any_port(AF_INET, port); } - if (streq(string, "%any6")) + if ((family == AF_UNSPEC || family == AF_INET6) && streq(string, "%any6")) { return host_create_any_port(AF_INET6, port); } - - this = host_create_empty(); - if (strchr(string, '.')) - { - this->address.sa_family = AF_INET; - } - else - { - this->address.sa_family = AF_INET6; - } - switch (this->address.sa_family) + switch (family) { - case AF_INET: - { - if (inet_pton(AF_INET, string, &this->address4.sin_addr) <=0) + case AF_UNSPEC: + if (strchr(string, '.')) { - break; + goto af_inet; } - this->address4.sin_port = htons(port); - this->socklen = sizeof(struct sockaddr_in); - return &this->public; - } + /* FALL */ case AF_INET6: - { - if (inet_pton(AF_INET6, string, &this->address6.sin6_addr) <=0) + if (inet_pton(AF_INET6, string, &addr.v6.sin6_addr) != 1) { - break; + return NULL; } - this->address6.sin6_port = htons(port); - this->socklen = sizeof(struct sockaddr_in6); - return &this->public; - } + addr.v6.sin6_port = htons(port); + addr.sockaddr.sa_family = AF_INET6; + return host_create_from_sockaddr(&addr.sockaddr); + case AF_INET: + af_inet: + if (inet_pton(AF_INET, string, &addr.v4.sin_addr) != 1) + { + return NULL; + } + addr.v4.sin_port = htons(port); + addr.sockaddr.sa_family = AF_INET; + return host_create_from_sockaddr(&addr.sockaddr); default: - { - break; - } + return NULL; } - free(this); - return NULL; +} + +/* + * Described in header. + */ +host_t *host_create_from_string(char *string, u_int16_t port) +{ + return host_create_from_string_and_family(string, AF_UNSPEC, port); } /* diff --git a/src/libstrongswan/networking/host.h b/src/libstrongswan/networking/host.h index 1c49b1a50..25f334779 100644 --- a/src/libstrongswan/networking/host.h +++ b/src/libstrongswan/networking/host.h @@ -160,6 +160,17 @@ struct host_t { host_t *host_create_from_string(char *string, u_int16_t port); /** + * Same as host_create_from_string(), but with the option to enforce a family. + * + * @param string string of an address + * @param family address family, or AF_UNSPEC + * @param port port number + * @return host_t, NULL if string not an address. + */ +host_t *host_create_from_string_and_family(char *string, int family, + u_int16_t port); + +/** * Constructor to create a host_t from a DNS name. * * @param string hostname to resolve |