diff options
Diffstat (limited to 'src/charon/network/socket.c')
-rw-r--r-- | src/charon/network/socket.c | 109 |
1 files changed, 64 insertions, 45 deletions
diff --git a/src/charon/network/socket.c b/src/charon/network/socket.c index 60ea5f7c8..6be59ef62 100644 --- a/src/charon/network/socket.c +++ b/src/charon/network/socket.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger + * Copyright (C) 2006-2008 Tobias Brunner + * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -14,7 +15,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: socket.c 3870 2008-04-24 13:49:20Z martin $ + * $Id: socket.c 4646 2008-11-13 07:15:45Z martin $ */ /* for struct in6_pktinfo */ @@ -33,7 +34,7 @@ #include <netinet/ip.h> #include <netinet/ip6.h> #include <netinet/udp.h> -#include <linux/ipsec.h> +#include <linux/types.h> #include <linux/filter.h> #include <net/if.h> @@ -44,11 +45,6 @@ /* length of non-esp marker */ #define MARKER_LEN sizeof(u_int32_t) -/* from linux/in.h */ -#ifndef IP_IPSEC_POLICY -#define IP_IPSEC_POLICY 16 -#endif /*IP_IPSEC_POLICY*/ - /* from linux/udp.h */ #ifndef UDP_ENCAP #define UDP_ENCAP 100 @@ -405,8 +401,7 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port) int on = TRUE; int type = UDP_ENCAP_ESPINUDP; struct sockaddr_storage addr; - u_int sol, ipsec_policy, pktinfo; - struct sadb_x_policy policy; + u_int sol, pktinfo; int skt; memset(&addr, 0, sizeof(addr)); @@ -420,7 +415,6 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port) sin->sin_addr.s_addr = INADDR_ANY; sin->sin_port = htons(port); sol = SOL_IP; - ipsec_policy = IP_IPSEC_POLICY; pktinfo = IP_PKTINFO; break; } @@ -431,7 +425,6 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port) memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any)); sin6->sin6_port = htons(port); sol = SOL_IPV6; - ipsec_policy = IPV6_IPSEC_POLICY; pktinfo = IPV6_2292PKTINFO; break; } @@ -452,29 +445,6 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port) return 0; } - /* bypass IKE traffic on socket */ - memset(&policy, 0, sizeof(policy)); - policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t); - policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY; - policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS; - - policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND; - if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0) - { - DBG1(DBG_NET, "unable to set IPSEC_POLICY on socket: %s", - strerror(errno)); - close(skt); - return 0; - } - policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND; - if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0) - { - DBG1(DBG_NET, "unable to set IPSEC_POLICY on socket: %s", - strerror(errno)); - close(skt); - return 0; - } - /* bind the send socket */ if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) < 0) { @@ -501,6 +471,64 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port) } /** + * enumerator for underlying sockets + */ +typedef struct { + /** implements enumerator_t */ + enumerator_t public; + /** sockets we enumerate */ + private_socket_t *socket; + /** counter */ + int index; +} socket_enumerator_t; + +/** + * enumerate function for socket_enumerator_t + */ +static bool enumerate(socket_enumerator_t *this, int *fd, int *family, int *port) +{ + static const struct { + int fd_offset; + int family; + int port; + } sockets[] = { + { offsetof(private_socket_t, ipv4), AF_INET, IKEV2_UDP_PORT }, + { offsetof(private_socket_t, ipv6), AF_INET6, IKEV2_UDP_PORT }, + { offsetof(private_socket_t, ipv4_natt), AF_INET, IKEV2_NATT_PORT }, + { offsetof(private_socket_t, ipv6_natt), AF_INET6, IKEV2_NATT_PORT } + }; + + while(++this->index < countof(sockets)) + { + int sock = *(int*)((char*)this->socket + sockets[this->index].fd_offset); + if (!sock) + { + continue; + } + *fd = sock; + *family = sockets[this->index].family; + *port = sockets[this->index].port; + return TRUE; + } + return FALSE; +} + +/** + * implementation of socket_t.create_enumerator + */ +static enumerator_t *create_enumerator(private_socket_t *this) +{ + socket_enumerator_t *enumerator; + + enumerator = malloc_thing(socket_enumerator_t); + enumerator->index = -1; + enumerator->socket = this; + enumerator->public.enumerate = (void*)enumerate; + enumerator->public.destroy = (void*)free; + return &enumerator->public; +} + +/** * implementation of socket_t.destroy */ static void destroy(private_socket_t *this) @@ -529,12 +557,12 @@ static void destroy(private_socket_t *this) */ socket_t *socket_create() { - int key; private_socket_t *this = malloc_thing(private_socket_t); /* public functions */ this->public.send = (status_t(*)(socket_t*, packet_t*))sender; this->public.receive = (status_t(*)(socket_t*, packet_t**))receiver; + this->public.create_enumerator = (enumerator_t*(*)(socket_t*))create_enumerator; this->public.destroy = (void(*)(socket_t*)) destroy; this->ipv4 = 0; @@ -542,15 +570,6 @@ socket_t *socket_create() this->ipv4_natt = 0; this->ipv6_natt = 0; - /* we open a AF_KEY socket to autoload the af_key module. Otherwise - * setsockopt(IPSEC_POLICY) won't work. */ - key = socket(AF_KEY, SOCK_RAW, PF_KEY_V2); - if (key == 0) - { - charon->kill(charon, "could not open AF_KEY socket"); - } - close(key); - this->ipv4 = open_socket(this, AF_INET, IKEV2_UDP_PORT); if (this->ipv4 == 0) { |