merging kernel_klips plugin back into trunk

This commit is contained in:
Tobias Brunner
2008-11-11 09:22:00 +00:00
parent c117f24e61
commit ea625fabf9
30 changed files with 3774 additions and 262 deletions
+64 -44
View File
@@ -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
@@ -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
@@ -100,6 +96,18 @@ struct private_socket_t {
int ipv6_natt;
};
/**
* enumerator for underlying sockets
*/
typedef struct {
/** implements enumerator_t */
enumerator_t public;
/** sockets we enumerate */
private_socket_t *socket;
/** counter */
u_int8_t index;
} socket_enumerator_t;
/**
* implementation of socket_t.receive
*/
@@ -405,8 +413,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 +427,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 +437,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 +457,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)
{
@@ -500,6 +482,53 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
return skt;
}
/**
* 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[] = {
{ 0, 0, 0 },
{ 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 <= 4)
{
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 = 0;
enumerator->socket = this;
enumerator->public.enumerate = (void*)enumerate;
enumerator->public.destroy = (void*)free;
return &enumerator->public;
}
/**
* implementation of socket_t.destroy
*/
@@ -529,12 +558,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 +571,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)
{