Add a host_t constructor from string, but with a specific family

This commit is contained in:
Martin Willi
2012-11-29 10:22:51 +01:00
parent d88597f0dd
commit f5fe52bf9a
2 changed files with 48 additions and 35 deletions
+37 -35
View File
@@ -358,57 +358,59 @@ static host_t *host_create_any_port(int family, u_int16_t port)
/* /*
* Described in header. * 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); 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); return host_create_any_port(AF_INET6, port);
} }
switch (family)
this = host_create_empty();
if (strchr(string, '.'))
{ {
this->address.sa_family = AF_INET; case AF_UNSPEC:
} if (strchr(string, '.'))
else
{
this->address.sa_family = AF_INET6;
}
switch (this->address.sa_family)
{
case AF_INET:
{
if (inet_pton(AF_INET, string, &this->address4.sin_addr) <=0)
{ {
break; goto af_inet;
} }
this->address4.sin_port = htons(port); /* FALL */
this->socklen = sizeof(struct sockaddr_in);
return &this->public;
}
case AF_INET6: case AF_INET6:
{ if (inet_pton(AF_INET6, string, &addr.v6.sin6_addr) != 1)
if (inet_pton(AF_INET6, string, &this->address6.sin6_addr) <=0)
{ {
break; return NULL;
} }
this->address6.sin6_port = htons(port); addr.v6.sin6_port = htons(port);
this->socklen = sizeof(struct sockaddr_in6); addr.sockaddr.sa_family = AF_INET6;
return &this->public; 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: default:
{ return NULL;
break;
}
} }
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);
} }
/* /*
+11
View File
@@ -159,6 +159,17 @@ struct host_t {
*/ */
host_t *host_create_from_string(char *string, u_int16_t port); 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. * Constructor to create a host_t from a DNS name.
* *