added raw socket filter for IPv6
This commit is contained in:
+12
-17
@@ -136,7 +136,6 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
|
|||||||
char buffer[MAX_PACKET];
|
char buffer[MAX_PACKET];
|
||||||
chunk_t data;
|
chunk_t data;
|
||||||
packet_t *pkt;
|
packet_t *pkt;
|
||||||
struct iphdr *ip;
|
|
||||||
struct udphdr *udp;
|
struct udphdr *udp;
|
||||||
host_t *source = NULL, *dest = NULL;
|
host_t *source = NULL, *dest = NULL;
|
||||||
int bytes_read = 0;
|
int bytes_read = 0;
|
||||||
@@ -162,7 +161,9 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
|
|||||||
{
|
{
|
||||||
/* IPv4 raw sockets return the IP header. We read src/dest
|
/* IPv4 raw sockets return the IP header. We read src/dest
|
||||||
* information directly from the raw header */
|
* information directly from the raw header */
|
||||||
|
struct iphdr *ip;
|
||||||
struct sockaddr_in src, dst;
|
struct sockaddr_in src, dst;
|
||||||
|
|
||||||
bytes_read = recv(this->recv4, buffer, MAX_PACKET, 0);
|
bytes_read = recv(this->recv4, buffer, MAX_PACKET, 0);
|
||||||
if (bytes_read < 0)
|
if (bytes_read < 0)
|
||||||
{
|
{
|
||||||
@@ -213,7 +214,7 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
|
|||||||
}
|
}
|
||||||
else if (FD_ISSET(this->recv6, &rfds))
|
else if (FD_ISSET(this->recv6, &rfds))
|
||||||
{
|
{
|
||||||
/* IPv6 raw sockets return the no IP header. We must query
|
/* IPv6 raw sockets return no IP header. We must query
|
||||||
* src/dest via socket options/ancillary data */
|
* src/dest via socket options/ancillary data */
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct cmsghdr *cmsgptr;
|
struct cmsghdr *cmsgptr;
|
||||||
@@ -626,7 +627,7 @@ static int open_recv_socket(private_socket_t *this, int family)
|
|||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
proto_offset = IP6_PROTO_OFFSET;
|
proto_offset = IP6_PROTO_OFFSET;
|
||||||
ip_len = IP6_LEN;
|
ip_len = 0; /* IPv6 raw sockets contain no IP header */
|
||||||
ip_proto = IPPROTO_IPV6;
|
ip_proto = IPPROTO_IPV6;
|
||||||
ip_pktinfo = IPV6_PKTINFO;
|
ip_pktinfo = IPV6_PKTINFO;
|
||||||
ipsec_policy = IPV6_IPSEC_POLICY;
|
ipsec_policy = IPV6_IPSEC_POLICY;
|
||||||
@@ -643,9 +644,6 @@ static int open_recv_socket(private_socket_t *this, int family)
|
|||||||
*/
|
*/
|
||||||
struct sock_filter ikev2_filter_code[] =
|
struct sock_filter ikev2_filter_code[] =
|
||||||
{
|
{
|
||||||
/* Protocol must be UDP */
|
|
||||||
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, proto_offset),
|
|
||||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_UDP, 0, 15),
|
|
||||||
/* Destination Port must be either port or natt_port */
|
/* Destination Port must be either port or natt_port */
|
||||||
BPF_STMT(BPF_LD+BPF_H+BPF_ABS, udp_header + 2),
|
BPF_STMT(BPF_LD+BPF_H+BPF_ABS, udp_header + 2),
|
||||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, this->port, 1, 0),
|
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, this->port, 1, 0),
|
||||||
@@ -689,17 +687,14 @@ static int open_recv_socket(private_socket_t *this, int family)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (family == AF_INET)
|
if (setsockopt(skt, SOL_SOCKET, SO_ATTACH_FILTER,
|
||||||
|
&ikev2_filter, sizeof(ikev2_filter)) < 0)
|
||||||
{
|
{
|
||||||
if (setsockopt(skt, SOL_SOCKET, SO_ATTACH_FILTER,
|
this->logger->log(this->logger, ERROR,
|
||||||
&ikev2_filter, sizeof(ikev2_filter)) < 0)
|
"unable to attach IKEv2 filter to raw socket: %s",
|
||||||
{
|
strerror(errno));
|
||||||
this->logger->log(this->logger, ERROR,
|
close(skt);
|
||||||
"unable to attach IKEv2 filter to raw socket: %s",
|
return 0;
|
||||||
strerror(errno));
|
|
||||||
close(skt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (setsockopt(skt, ip_proto, ip_pktinfo, &on, sizeof(on)) < 0)
|
else if (setsockopt(skt, ip_proto, ip_pktinfo, &on, sizeof(on)) < 0)
|
||||||
@@ -840,7 +835,7 @@ socket_t *socket_create(u_int16_t port, u_int16_t natt_port)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(this->send4 || this->send6))
|
if (!(this->send4 || this->send6) || !(this->recv4 || this->recv6))
|
||||||
{
|
{
|
||||||
this->logger->log(this->logger, ERROR,
|
this->logger->log(this->logger, ERROR,
|
||||||
"could not create any sockets");
|
"could not create any sockets");
|
||||||
|
|||||||
@@ -45,9 +45,9 @@
|
|||||||
typedef struct socket_t socket_t;
|
typedef struct socket_t socket_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Abstraction all sockets (currently IPv4 only).
|
* @brief Abstraction of all sockets (IPv6/IPv6 send/receive).
|
||||||
*
|
*
|
||||||
* All available IPv4 sockets are bound and the receive function
|
* All available sockets are bound and the receive function
|
||||||
* reads from them. To allow binding of other daemons (pluto) to
|
* reads from them. To allow binding of other daemons (pluto) to
|
||||||
* UDP/500, this implementation uses RAW sockets. An installed
|
* UDP/500, this implementation uses RAW sockets. An installed
|
||||||
* "Linux socket filter" filters out all non-IKEv2 traffic and handles
|
* "Linux socket filter" filters out all non-IKEv2 traffic and handles
|
||||||
@@ -120,8 +120,6 @@ struct socket_t {
|
|||||||
/**
|
/**
|
||||||
* @brief Create a socket_t, wich binds multiple sockets.
|
* @brief Create a socket_t, wich binds multiple sockets.
|
||||||
*
|
*
|
||||||
* currently creates a raw socket and two send sockets
|
|
||||||
*
|
|
||||||
* @param port port to bind socket to
|
* @param port port to bind socket to
|
||||||
* @param natt_port port to float to in NAT-T
|
* @param natt_port port to float to in NAT-T
|
||||||
* @return socket_t object
|
* @return socket_t object
|
||||||
|
|||||||
Reference in New Issue
Block a user