diff options
Diffstat (limited to 'src/libstrongswan/utils/host.c')
-rw-r--r-- | src/libstrongswan/utils/host.c | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c index cfcb87373..8c79f718a 100644 --- a/src/libstrongswan/utils/host.c +++ b/src/libstrongswan/utils/host.c @@ -504,38 +504,56 @@ host_t *host_create_from_dns(char *string, int af, u_int16_t port) */ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port) { - private_host_t *this = host_create_empty(); + private_host_t *this; - this->address.sa_family = family; switch (family) { case AF_INET: - { - if (address.len != IPV4_LEN) + if (address.len < IPV4_LEN) { - break; + return NULL; } - memcpy(&(this->address4.sin_addr.s_addr), address.ptr, IPV4_LEN); - this->address4.sin_port = htons(port); - this->socklen = sizeof(struct sockaddr_in); - return &(this->public); - } + address.len = IPV4_LEN; + break; case AF_INET6: - { - if (address.len != IPV6_LEN) + if (address.len < IPV6_LEN) { - break; + return NULL; } - memcpy(&(this->address6.sin6_addr.s6_addr), address.ptr, IPV6_LEN); + address.len = IPV6_LEN; + break; + case AF_UNSPEC: + switch (address.len) + { + case IPV4_LEN: + family = AF_INET; + break; + case IPV6_LEN: + family = AF_INET6; + break; + default: + return NULL; + } + break; + default: + return NULL; + } + this = host_create_empty(); + this->address.sa_family = family; + switch (family) + { + case AF_INET: + memcpy(&this->address4.sin_addr.s_addr, address.ptr, address.len); + this->address4.sin_port = htons(port); + this->socklen = sizeof(struct sockaddr_in); + break; + case AF_INET6: + memcpy(&this->address6.sin6_addr.s6_addr, address.ptr, address.len); this->address6.sin6_port = htons(port); this->socklen = sizeof(struct sockaddr_in6); - return &this->public; - } - default: break; } - free(this); - return NULL; + return &this->public; } /* |