merging changes from portability branch back to trunk
important change for developers: %Y replaces %D to print identities!
This commit is contained in:
+53
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2006-2008 Tobias Brunner
|
||||
* Copyright (C) 2006-2009 Tobias Brunner
|
||||
* Copyright (C) 2006 Daniel Roethlisberger
|
||||
* Copyright (C) 2005-2007 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -30,12 +30,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/filter.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "socket.h"
|
||||
@@ -54,10 +53,12 @@
|
||||
#define UDP_ENCAP_ESPINUDP 2
|
||||
#endif /*UDP_ENCAP_ESPINUDP*/
|
||||
|
||||
/* needed for older kernel headers */
|
||||
#ifndef IPV6_2292PKTINFO
|
||||
#define IPV6_2292PKTINFO 2
|
||||
#endif /*IPV6_2292PKTINFO*/
|
||||
/* these are not defined on some platforms */
|
||||
#ifndef SOL_IP
|
||||
#define SOL_IP IPPROTO_IP
|
||||
#define SOL_IPV6 IPPROTO_IPV6
|
||||
#define SOL_UDP IPPROTO_UDP
|
||||
#endif
|
||||
|
||||
typedef struct private_socket_t private_socket_t;
|
||||
|
||||
@@ -201,7 +202,7 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
|
||||
}
|
||||
|
||||
if (cmsgptr->cmsg_level == SOL_IPV6 &&
|
||||
cmsgptr->cmsg_type == IPV6_2292PKTINFO)
|
||||
cmsgptr->cmsg_type == IPV6_PKTINFO)
|
||||
{
|
||||
struct in6_pktinfo *pktinfo;
|
||||
pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr);
|
||||
@@ -214,14 +215,26 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
|
||||
dest = host_create_from_sockaddr((sockaddr_t*)&dst);
|
||||
}
|
||||
if (cmsgptr->cmsg_level == SOL_IP &&
|
||||
cmsgptr->cmsg_type == IP_PKTINFO)
|
||||
{
|
||||
#ifdef IP_RECVDSTADDR
|
||||
cmsgptr->cmsg_type == IP_RECVDSTADDR
|
||||
#else
|
||||
cmsgptr->cmsg_type == IP_PKTINFO
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct in_addr *addr;
|
||||
struct sockaddr_in dst;
|
||||
|
||||
#ifdef IP_RECVDSTADDR
|
||||
addr = (struct in_addr*)CMSG_DATA(cmsgptr);
|
||||
#else
|
||||
struct in_pktinfo *pktinfo;
|
||||
pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr);
|
||||
struct sockaddr_in dst;
|
||||
|
||||
addr = &pktinfo->ipi_addr;
|
||||
#endif
|
||||
memset(&dst, 0, sizeof(dst));
|
||||
memcpy(&dst.sin_addr, &pktinfo->ipi_addr, sizeof(dst.sin_addr));
|
||||
memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr));
|
||||
|
||||
dst.sin_family = AF_INET;
|
||||
dst.sin_port = htons(port);
|
||||
dest = host_create_from_sockaddr((sockaddr_t*)&dst);
|
||||
@@ -340,24 +353,35 @@ status_t sender(private_socket_t *this, packet_t *packet)
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_flags = 0;
|
||||
|
||||
if (!dst->is_anyaddr(dst))
|
||||
if (!src->is_anyaddr(src))
|
||||
{
|
||||
if (family == AF_INET)
|
||||
{
|
||||
struct in_addr *addr;
|
||||
struct sockaddr_in *sin;
|
||||
#ifdef IP_SENDSRCADDR
|
||||
char buf[CMSG_SPACE(sizeof(struct in_addr))];
|
||||
#else
|
||||
char buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
|
||||
struct in_pktinfo *pktinfo;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
#endif
|
||||
msg.msg_control = buf;
|
||||
msg.msg_controllen = sizeof(buf);
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_level = SOL_IP;
|
||||
#ifdef IP_SENDSRCADDR
|
||||
cmsg->cmsg_type = IP_SENDSRCADDR;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
|
||||
addr = (struct in_addr*)CMSG_DATA(cmsg);
|
||||
#else
|
||||
cmsg->cmsg_type = IP_PKTINFO;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
|
||||
pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
|
||||
memset(pktinfo, 0, sizeof(struct in_pktinfo));
|
||||
addr = &pktinfo->ipi_spec_dst;
|
||||
#endif
|
||||
sin = (struct sockaddr_in*)src->get_sockaddr(src);
|
||||
memcpy(&pktinfo->ipi_spec_dst, &sin->sin_addr, sizeof(struct in_addr));
|
||||
memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -369,7 +393,7 @@ status_t sender(private_socket_t *this, packet_t *packet)
|
||||
msg.msg_controllen = sizeof(buf);
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_level = SOL_IPV6;
|
||||
cmsg->cmsg_type = IPV6_2292PKTINFO;
|
||||
cmsg->cmsg_type = IPV6_PKTINFO;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
||||
pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
|
||||
memset(pktinfo, 0, sizeof(struct in6_pktinfo));
|
||||
@@ -389,13 +413,14 @@ status_t sender(private_socket_t *this, packet_t *packet)
|
||||
}
|
||||
|
||||
/**
|
||||
* open a socket to send packets
|
||||
* open a socket to send and receive packets
|
||||
*/
|
||||
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;
|
||||
socklen_t addrlen;
|
||||
u_int sol, pktinfo;
|
||||
int skt;
|
||||
|
||||
@@ -409,8 +434,13 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr.s_addr = INADDR_ANY;
|
||||
sin->sin_port = htons(port);
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
sol = SOL_IP;
|
||||
#ifdef IP_RECVDSTADDR
|
||||
pktinfo = IP_RECVDSTADDR;
|
||||
#else
|
||||
pktinfo = IP_PKTINFO;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case AF_INET6:
|
||||
@@ -419,8 +449,9 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
|
||||
sin6->sin6_family = AF_INET6;
|
||||
memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
|
||||
sin6->sin6_port = htons(port);
|
||||
addrlen = sizeof(struct sockaddr_in6);
|
||||
sol = SOL_IPV6;
|
||||
pktinfo = IPV6_2292PKTINFO;
|
||||
pktinfo = IPV6_RECVPKTINFO;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -440,8 +471,8 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* bind the send socket */
|
||||
if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
||||
/* bind the socket */
|
||||
if (bind(skt, (struct sockaddr *)&addr, addrlen) < 0)
|
||||
{
|
||||
DBG1(DBG_NET, "unable to bind socket: %s", strerror(errno));
|
||||
close(skt);
|
||||
|
||||
Reference in New Issue
Block a user