testing: Accept LANG and LC_* env variables via SSH on guests
[strongswan.git] / src / libstrongswan / networking / host.c
index 268d9b1..110ece8 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * Copyright (C) 2006-2012 Tobias Brunner
+ * Copyright (C) 2006-2014 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
+ * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -79,7 +79,7 @@ METHOD(host_t, get_sockaddr_len, socklen_t*,
 METHOD(host_t, is_anyaddr, bool,
        private_host_t *this)
 {
-       static const u_int8_t zeroes[IPV6_LEN];
+       static const uint8_t zeroes[IPV6_LEN];
 
        switch (this->address.sa_family)
        {
@@ -111,7 +111,7 @@ int host_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
        {
                snprintf(buffer, sizeof(buffer), "(null)");
        }
-       else if (is_anyaddr(this) && !spec->plus)
+       else if (is_anyaddr(this) && !spec->plus && !spec->hash)
        {
                snprintf(buffer, sizeof(buffer), "%%any%s",
                                 this->address.sa_family == AF_INET6 ? "6" : "");
@@ -119,7 +119,7 @@ int host_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
        else
        {
                void *address;
-               u_int16_t port;
+               uint16_t port;
                int len;
 
                address = &this->address6.sin6_addr;
@@ -139,7 +139,7 @@ int host_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
                                        snprintf(buffer, sizeof(buffer),
                                                         "(address conversion failed)");
                                }
-                               else if (spec->hash)
+                               else if (spec->hash && port)
                                {
                                        len = strlen(buffer);
                                        snprintf(buffer + len, sizeof(buffer) - len,
@@ -191,7 +191,7 @@ METHOD(host_t, get_family, int,
        return this->address.sa_family;
 }
 
-METHOD(host_t, get_port, u_int16_t,
+METHOD(host_t, get_port, uint16_t,
        private_host_t *this)
 {
        switch (this->address.sa_family)
@@ -212,7 +212,7 @@ METHOD(host_t, get_port, u_int16_t,
 }
 
 METHOD(host_t, set_port, void,
-       private_host_t *this, u_int16_t port)
+       private_host_t *this, uint16_t port)
 {
        switch (this->address.sa_family)
        {
@@ -274,26 +274,6 @@ static bool ip_equals(private_host_t *this, private_host_t *other)
 }
 
 /**
- * Implements host_t.get_differences
- */
-static host_diff_t get_differences(host_t *this, host_t *other)
-{
-       host_diff_t ret = HOST_DIFF_NONE;
-
-       if (!this->ip_equals(this, other))
-       {
-               ret |= HOST_DIFF_ADDR;
-       }
-
-       if (this->get_port(this) != other->get_port(other))
-       {
-               ret |= HOST_DIFF_PORT;
-       }
-
-       return ret;
-}
-
-/**
  * Implements host_t.equals
  */
 static bool equals(private_host_t *this, private_host_t *other)
@@ -341,7 +321,6 @@ static private_host_t *host_create_empty(void)
                        .get_address = _get_address,
                        .get_port = _get_port,
                        .set_port = _set_port,
-                       .get_differences = get_differences,
                        .ip_equals = (bool (*)(host_t *,host_t *))ip_equals,
                        .equals = (bool (*)(host_t *,host_t *)) equals,
                        .is_anyaddr = _is_anyaddr,
@@ -355,7 +334,7 @@ static private_host_t *host_create_empty(void)
 /*
  * Create a %any host with port
  */
-static host_t *host_create_any_port(int family, u_int16_t port)
+static host_t *host_create_any_port(int family, uint16_t port)
 {
        host_t *this;
 
@@ -368,13 +347,17 @@ static host_t *host_create_any_port(int family, u_int16_t port)
  * Described in header.
  */
 host_t *host_create_from_string_and_family(char *string, int family,
-                                                                                  u_int16_t port)
+                                                                                  uint16_t port)
 {
        union {
                struct sockaddr_in v4;
                struct sockaddr_in6 v6;
        } addr;
 
+       if (!string)
+       {
+               return NULL;
+       }
        if (streq(string, "%any"))
        {
                return host_create_any_port(family ? family : AF_INET, port);
@@ -402,6 +385,7 @@ host_t *host_create_from_string_and_family(char *string, int family,
                        }
                        /* FALL */
                case AF_INET6:
+                       memset(&addr.v6, 0, sizeof(addr.v6));
                        if (inet_pton(AF_INET6, string, &addr.v6.sin6_addr) != 1)
                        {
                                return NULL;
@@ -415,6 +399,7 @@ host_t *host_create_from_string_and_family(char *string, int family,
                                return NULL;
                        }
                af_inet:
+                       memset(&addr.v4, 0, sizeof(addr.v4));
                        if (inet_pton(AF_INET, string, &addr.v4.sin_addr) != 1)
                        {
                                return NULL;
@@ -430,7 +415,7 @@ host_t *host_create_from_string_and_family(char *string, int family,
 /*
  * Described in header.
  */
-host_t *host_create_from_string(char *string, u_int16_t port)
+host_t *host_create_from_string(char *string, uint16_t port)
 {
        return host_create_from_string_and_family(string, AF_UNSPEC, port);
 }
@@ -470,7 +455,7 @@ host_t *host_create_from_sockaddr(sockaddr_t *sockaddr)
 /*
  * Described in header.
  */
-host_t *host_create_from_dns(char *string, int af, u_int16_t port)
+host_t *host_create_from_dns(char *string, int af, uint16_t port)
 {
        host_t *this;
 
@@ -489,7 +474,7 @@ host_t *host_create_from_dns(char *string, int af, u_int16_t port)
 /*
  * Described in header.
  */
-host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port)
+host_t *host_create_from_chunk(int family, chunk_t address, uint16_t port)
 {
        private_host_t *this;
 
@@ -547,6 +532,42 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port)
 /*
  * Described in header.
  */
+bool host_create_from_range(char *string, host_t **from, host_t **to)
+{
+       char *sep, *pos;
+
+       sep = strchr(string, '-');
+       if (!sep)
+       {
+               return FALSE;
+       }
+       for (pos = sep+1; *pos && *pos == ' '; pos++)
+       {
+               /* trim spaces before to address*/
+       }
+       *to = host_create_from_string(pos, 0);
+       if (!*to)
+       {
+               return FALSE;
+       }
+       for (pos = sep-1; pos > string && *pos == ' '; pos--)
+       {
+               /* trim spaces behind from address */
+       }
+       pos = strndup(string, pos - string + 1);
+       *from = host_create_from_string_and_family(pos, (*to)->get_family(*to), 0);
+       free(pos);
+       if (!*from)
+       {
+               (*to)->destroy(*to);
+               return FALSE;
+       }
+       return TRUE;
+}
+
+/*
+ * Described in header.
+ */
 host_t *host_create_from_subnet(char *string, int *bits)
 {
        char *pos, buf[64];
@@ -580,6 +601,57 @@ host_t *host_create_from_subnet(char *string, int *bits)
 }
 
 /*
+ * See header.
+ */
+host_t *host_create_netmask(int family, int netbits)
+{
+       private_host_t *this;
+       int bits, bytes, len = 0;
+       char *target;
+
+       switch (family)
+       {
+               case AF_INET:
+                       if (netbits < 0 || netbits > 32)
+                       {
+                               return NULL;
+                       }
+                       this = host_create_empty();
+                       this->socklen = sizeof(struct sockaddr_in);
+                       target = (char*)&this->address4.sin_addr;
+                       len = 4;
+                       break;
+               case AF_INET6:
+                       if (netbits < 0 || netbits > 128)
+                       {
+                               return NULL;
+                       }
+                       this = host_create_empty();
+                       this->socklen = sizeof(struct sockaddr_in6);
+                       target = (char*)&this->address6.sin6_addr;
+                       len = 16;
+                       break;
+               default:
+                       return NULL;
+       }
+
+       memset(&this->address_max, 0, sizeof(struct sockaddr_storage));
+       this->address.sa_family = family;
+       update_sa_len(this);
+
+       bytes = netbits / 8;
+       bits = 8 - (netbits & 0x07);
+
+       memset(target, 0xff, bytes);
+       if (bytes < len)
+       {
+               memset(target + bytes, 0x00, len - bytes);
+               target[bytes] = (uint8_t)(0xff << bits);
+       }
+       return &this->public;
+}
+
+/*
  * Described in header.
  */
 host_t *host_create_any(int family)