diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 365d834e65bde81e8407cb75347e67308952c770..66855ca803a9949f9355b945bfa1e4c8a2ffd506 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -123,6 +123,7 @@ freebsd/x86_64: only: - branches@cwrap/socket_wrapper - branches@cryptomilk/socket_wrapper + - branches@metze/socket_wrapper artifacts: expire_in: 1 week when: on_failure diff --git a/doc/socket_wrapper.1 b/doc/socket_wrapper.1 index 9f3f75a30c6cdd7e82b5f4bdb5ee6fb742bf274a..e244f10946747edd6f5ca2280f81946903fd6800 100644 --- a/doc/socket_wrapper.1 +++ b/doc/socket_wrapper.1 @@ -75,9 +75,14 @@ Ability to capture network traffic in pcap format\&. The user defines a directory where to put all the unix sockets using the environment variable "SOCKET_WRAPPER_DIR=/path/to/socket_dir"\&. When a server opens a port or a client wants to connect, socket_wrapper will translate IP addresses to a special socket_wrapper name and look for the relevant Unix socket in the SOCKET_WRAPPER_DIR\&. .RE .PP +\fBSOCKET_WRAPPER_IPV4_NETWORK\fR +.RS 4 +By default the loopback IPv4 network "127\&.0\&.0\&.0/8" and the "127\&.0\&.0\&.x" can be used\&. In order to make more realistic testing possible it is possible to use the "10\&.0\&.0\&.0/8" IPv4 network instead\&. But note within "10\&.0\&.0\&.0/8" only "10\&.53\&.57\&." can be used, but the broadcast address is "10\&.255\&.255\&.255"\&. The following two value are allowed: SOCKET_WRAPPER_IPV4_NETWORK="127\&.0\&.0\&.0" (the default) and SOCKET_WRAPPER_IPV4_NETWORK="10\&.53\&.57\&.0"\&. +.RE +.PP \fBSOCKET_WRAPPER_DEFAULT_IFACE\fR .RS 4 -Additionally, the default interface to be used by an application is defined with "SOCKET_WRAPPER_DEFAULT_IFACE=" where is between 2 and 254\&. This is analogous to use the IPv4 addresses "127\&.0\&.0\&." or IPv6 addresses "fd00::5357:5f" (where is a hexadecimal presentation of )\&. You should always set the default interface\&. If you listen on INADDR_ANY then it will use the default interface to listen on\&. +Additionally, the default interface to be used by an application is defined with "SOCKET_WRAPPER_DEFAULT_IFACE=" where the valid range for starts with 1 (the default) and ends with 64\&. This is analogous to use the IPv4 addresses "127\&.0\&.0\&."/"10\&.53\&.57\&." or IPv6 addresses "fd00::5357:5f" (where is a hexadecimal presentation of )\&. You should always set the default interface\&. If you listen on INADDR_ANY then it will use the default interface to listen on\&. .RE .PP \fBSOCKET_WRAPPER_PCAP_FILE\fR diff --git a/doc/socket_wrapper.1.txt b/doc/socket_wrapper.1.txt index b3ba96cafdaec861d0f2e0cd3d4a9964410c0a8d..c00d5828042a9469b157c78f64fc9eb4a85b9968 100644 --- a/doc/socket_wrapper.1.txt +++ b/doc/socket_wrapper.1.txt @@ -36,14 +36,26 @@ opens a port or a client wants to connect, socket_wrapper will translate IP addresses to a special socket_wrapper name and look for the relevant Unix socket in the SOCKET_WRAPPER_DIR. +*SOCKET_WRAPPER_IPV4_NETWORK*:: + +By default the loopback IPv4 network "127.0.0.0/8" and the +"127.0.0.x" can be used. In order to make more realistic testing +possible it is possible to use the "10.0.0.0/8" IPv4 network instead. +But note within "10.0.0.0/8" only "10.53.57." can be used, +but the broadcast address is "10.255.255.255". +The following two value are allowed: +SOCKET_WRAPPER_IPV4_NETWORK="127.0.0.0" (the default) and +SOCKET_WRAPPER_IPV4_NETWORK="10.53.57.0". + *SOCKET_WRAPPER_DEFAULT_IFACE*:: -Additionally, the default interface to be used by an application is defined -with "SOCKET_WRAPPER_DEFAULT_IFACE=" where is between 2 and 254. This -is analogous to use the IPv4 addresses "127.0.0." or IPv6 addresses -"fd00::5357:5f" (where is a hexadecimal presentation of ). You -should always set the default interface. If you listen on INADDR_ANY then it -will use the default interface to listen on. +Additionally, the default interface to be used by an application is defined with +"SOCKET_WRAPPER_DEFAULT_IFACE=" where the valid range for starts with 1 +(the default) and ends with 64. This is analogous to use the IPv4 addresses +"127.0.0."/"10.53.57." or IPv6 addresses "fd00::5357:5f" (where + is a hexadecimal presentation of ). You should always set the default +interface. If you listen on INADDR_ANY then it will use the default interface to +listen on. *SOCKET_WRAPPER_PCAP_FILE*:: diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index bd15793f55cb572ed803b45c5758a68e98e904bb..cee7c51fc7616c1c48ce0a8211abc4d343de9e92 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -1192,6 +1192,94 @@ static void swrap_bind_symbol_all(void) * SWRAP HELPER FUNCTIONS *********************************************************/ +/* + * We return 127.0.0.0 (default) or 10.53.57.0. + * + * This can be controlled by: + * SOCKET_WRAPPER_IPV4_NETWORK=127.0.0.0 (default) + * or + * SOCKET_WRAPPER_IPV4_NETWORK=10.53.57.0 + */ +static in_addr_t swrap_ipv4_net(void) +{ + static int initialized; + static in_addr_t hv; + const char *net_str = NULL; + struct in_addr nv; + int ret; + + if (initialized) { + return hv; + } + initialized = 1; + + net_str = getenv("SOCKET_WRAPPER_IPV4_NETWORK"); + if (net_str == NULL) { + net_str = "127.0.0.0"; + } + + ret = inet_pton(AF_INET, net_str, &nv); + if (ret <= 0) { + SWRAP_LOG(SWRAP_LOG_ERROR, + "INVALID IPv4 Network [%s]\n", + net_str); + abort(); + } + + hv = ntohl(nv.s_addr); + + switch (hv) { + case 0x7f000000: + /* 127.0.0.0 */ + break; + case 0x0a353900: + /* 10.53.57.0 */ + break; + default: + SWRAP_LOG(SWRAP_LOG_ERROR, + "INVALID IPv4 Network [%s][0x%x] should be " + "127.0.0.0 or 10.53.57.0\n", + net_str, (unsigned)hv); + abort(); + } + + return hv; +} + +/* + * This returns 127.255.255.255 or 10.255.255.255 + */ +static in_addr_t swrap_ipv4_bcast(void) +{ + in_addr_t hv; + + hv = swrap_ipv4_net(); + hv |= IN_CLASSA_HOST; + + return hv; +} + +/* + * This returns 127.0.0.${iface} or 10.53.57.${iface} + */ +static in_addr_t swrap_ipv4_iface(unsigned int iface) +{ + in_addr_t hv; + + if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) { + SWRAP_LOG(SWRAP_LOG_ERROR, + "swrap_ipv4_iface(%u) invalid!\n", + iface); + abort(); + return -1; + } + + hv = swrap_ipv4_net(); + hv |= iface; + + return hv; +} + #ifdef HAVE_IPV6 /* * FD00::5357:5FXX @@ -1442,6 +1530,12 @@ static void socket_wrapper_init_sockets(void) return; } + /* + * Intialize the static cache early before + * any thread is able to start. + */ + (void)swrap_ipv4_net(); + socket_wrapper_init_fds_idx(); /* Needs to be called inside the sockets_mutex lock here. */ @@ -1684,7 +1778,7 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, sock memset(in2, 0, sizeof(*in2)); in2->sin_family = AF_INET; - in2->sin_addr.s_addr = htonl((127<<24) | iface); + in2->sin_addr.s_addr = htonl(swrap_ipv4_iface(iface)); in2->sin_port = htons(prt); *len = sizeof(*in2); @@ -1737,6 +1831,8 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i char u_type = '\0'; char b_type = '\0'; char a_type = '\0'; + const unsigned int sw_net_addr = swrap_ipv4_net(); + const unsigned int sw_bcast_addr = swrap_ipv4_bcast(); switch (si->type) { case SOCK_STREAM: @@ -1759,13 +1855,18 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i is_bcast = 2; type = a_type; iface = socket_wrapper_default_iface(); - } else if (b_type && addr == 0x7FFFFFFF) { - /* 127.255.255.255 only udp */ + } else if (b_type && addr == sw_bcast_addr) { + /* + * 127.255.255.255 + * or + * 10.255.255.255 + * only udp + */ is_bcast = 1; type = b_type; iface = socket_wrapper_default_iface(); - } else if ((addr & 0xFFFFFF00) == 0x7F000000) { - /* 127.0.0.X */ + } else if ((addr & 0xFFFFFF00) == sw_net_addr) { + /* 127.0.0.X or 10.53.57.X */ is_bcast = 0; type = u_type; iface = (addr & 0x000000FF); @@ -1869,6 +1970,8 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in char d_type = '\0'; char b_type = '\0'; char a_type = '\0'; + const unsigned int sw_net_addr = swrap_ipv4_net(); + const unsigned int sw_bcast_addr = swrap_ipv4_bcast(); prt = ntohs(in->sin_port); @@ -1899,12 +2002,12 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in is_bcast = 2; type = a_type; iface = socket_wrapper_default_iface(); - } else if (b_type && addr == 0x7FFFFFFF) { + } else if (b_type && addr == sw_bcast_addr) { /* 127.255.255.255 only udp */ is_bcast = 1; type = b_type; iface = socket_wrapper_default_iface(); - } else if ((addr & 0xFFFFFF00) == 0x7F000000) { + } else if ((addr & 0xFFFFFF00) == sw_net_addr) { /* 127.0.0.X */ is_bcast = 0; type = u_type; @@ -1922,8 +2025,7 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in ZERO_STRUCT(bind_in); bind_in.sin_family = in->sin_family; bind_in.sin_port = in->sin_port; - bind_in.sin_addr.s_addr = htonl(0x7F000000 | iface); - + bind_in.sin_addr.s_addr = htonl(swrap_ipv4_iface(iface)); si->bindname.sa_socklen = blen; memcpy(&si->bindname.sa.in, &bind_in, blen); } @@ -3554,8 +3656,8 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family) memset(&in, 0, sizeof(in)); in.sin_family = AF_INET; - in.sin_addr.s_addr = htonl(127<<24 | - socket_wrapper_default_iface()); + in.sin_addr.s_addr = htonl(swrap_ipv4_iface( + socket_wrapper_default_iface())); si->myname = (struct swrap_address) { .sa_socklen = sizeof(in),