fixing compilation of socket_t on systems that have neither IP_PKTINFO (Linux) nor IP_SENDSRCADDR (FreeBSD)

This commit is contained in:
Tobias Brunner
2009-05-12 17:40:43 +02:00
parent 0a3ca29021
commit 75a354bb6b
+32 -21
View File
@@ -54,7 +54,11 @@
/* these are not defined on some platforms */ /* these are not defined on some platforms */
#ifndef SOL_IP #ifndef SOL_IP
#define SOL_IP IPPROTO_IP #define SOL_IP IPPROTO_IP
#endif
#ifndef SOL_IPV6
#define SOL_IPV6 IPPROTO_IPV6 #define SOL_IPV6 IPPROTO_IPV6
#endif
#ifndef SOL_UDP
#define SOL_UDP IPPROTO_UDP #define SOL_UDP IPPROTO_UDP
#endif #endif
@@ -213,22 +217,24 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
dest = host_create_from_sockaddr((sockaddr_t*)&dst); dest = host_create_from_sockaddr((sockaddr_t*)&dst);
} }
if (cmsgptr->cmsg_level == SOL_IP && if (cmsgptr->cmsg_level == SOL_IP &&
#ifdef IP_RECVDSTADDR #ifdef IP_PKTINFO
cmsgptr->cmsg_type == IP_PKTINFO
#elif defined(IP_RECVDSTADDR)
cmsgptr->cmsg_type == IP_RECVDSTADDR cmsgptr->cmsg_type == IP_RECVDSTADDR
#else #else
cmsgptr->cmsg_type == IP_PKTINFO FALSE
#endif #endif
) )
{ {
struct in_addr *addr; struct in_addr *addr;
struct sockaddr_in dst; struct sockaddr_in dst;
#ifdef IP_RECVDSTADDR #ifdef IP_PKTINFO
addr = (struct in_addr*)CMSG_DATA(cmsgptr);
#else
struct in_pktinfo *pktinfo; struct in_pktinfo *pktinfo;
pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr); pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr);
addr = &pktinfo->ipi_addr; addr = &pktinfo->ipi_addr;
#elif defined(IP_RECVDSTADDR)
addr = (struct in_addr*)CMSG_DATA(cmsgptr);
#endif #endif
memset(&dst, 0, sizeof(dst)); memset(&dst, 0, sizeof(dst));
memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr)); memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr));
@@ -355,31 +361,33 @@ status_t sender(private_socket_t *this, packet_t *packet)
{ {
if (family == AF_INET) if (family == AF_INET)
{ {
#if defined(IP_PKTINFO) || defined(IP_SENDSRCADDR)
struct in_addr *addr; struct in_addr *addr;
struct sockaddr_in *sin; struct sockaddr_in *sin;
#ifdef IP_SENDSRCADDR #ifdef IP_PKTINFO
char buf[CMSG_SPACE(sizeof(struct in_addr))];
#else
char buf[CMSG_SPACE(sizeof(struct in_pktinfo))]; char buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
struct in_pktinfo *pktinfo; struct in_pktinfo *pktinfo;
#elif defined(IP_SENDSRCADDR)
char buf[CMSG_SPACE(sizeof(struct in_addr))];
#endif #endif
msg.msg_control = buf; msg.msg_control = buf;
msg.msg_controllen = sizeof(buf); msg.msg_controllen = sizeof(buf);
cmsg = CMSG_FIRSTHDR(&msg); cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_IP; cmsg->cmsg_level = SOL_IP;
#ifdef IP_SENDSRCADDR #ifdef IP_PKTINFO
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_type = IP_PKTINFO;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg); pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
memset(pktinfo, 0, sizeof(struct in_pktinfo)); memset(pktinfo, 0, sizeof(struct in_pktinfo));
addr = &pktinfo->ipi_spec_dst; addr = &pktinfo->ipi_spec_dst;
#elif defined(IP_SENDSRCADDR)
cmsg->cmsg_type = IP_SENDSRCADDR;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
addr = (struct in_addr*)CMSG_DATA(cmsg);
#endif #endif
sin = (struct sockaddr_in*)src->get_sockaddr(src); sin = (struct sockaddr_in*)src->get_sockaddr(src);
memcpy(addr, &sin->sin_addr, sizeof(struct in_addr)); memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
#endif /* IP_PKTINFO || IP_SENDSRCADDR */
} }
else else
{ {
@@ -419,7 +427,7 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
int type = UDP_ENCAP_ESPINUDP; int type = UDP_ENCAP_ESPINUDP;
struct sockaddr_storage addr; struct sockaddr_storage addr;
socklen_t addrlen; socklen_t addrlen;
u_int sol, pktinfo; u_int sol, pktinfo = 0;
int skt; int skt;
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
@@ -434,10 +442,10 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
sin->sin_port = htons(port); sin->sin_port = htons(port);
addrlen = sizeof(struct sockaddr_in); addrlen = sizeof(struct sockaddr_in);
sol = SOL_IP; sol = SOL_IP;
#ifdef IP_RECVDSTADDR #ifdef IP_PKTINFO
pktinfo = IP_RECVDSTADDR;
#else
pktinfo = IP_PKTINFO; pktinfo = IP_PKTINFO;
#elif defined(IP_RECVDSTADDR)
pktinfo = IP_RECVDSTADDR;
#endif #endif
break; break;
} }
@@ -478,11 +486,14 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
} }
/* get additional packet info on receive */ /* get additional packet info on receive */
if (setsockopt(skt, sol, pktinfo, &on, sizeof(on)) < 0) if (pktinfo > 0)
{ {
DBG1(DBG_NET, "unable to set IP_PKTINFO on socket: %s", strerror(errno)); if (setsockopt(skt, sol, pktinfo, &on, sizeof(on)) < 0)
close(skt); {
return 0; DBG1(DBG_NET, "unable to set IP_PKTINFO on socket: %s", strerror(errno));
close(skt);
return 0;
}
} }
/* enable UDP decapsulation globally, only for one socket needed */ /* enable UDP decapsulation globally, only for one socket needed */