170 lines
4.5 KiB
C
170 lines
4.5 KiB
C
$NetBSD: patch-network.c,v 1.4 2015/02/19 22:27:59 joerg Exp $
|
|
|
|
Handle not having IP_PKTINFO
|
|
Handle not having SO_NO_CHECK
|
|
Don't set control buf if controllen == 0
|
|
Avoid pointer aliasing issue and fix test that was done in the wrong
|
|
byte order
|
|
|
|
--- network.c.orig 2014-01-16 22:02:04.000000000 +0000
|
|
+++ network.c
|
|
@@ -85,24 +85,26 @@ int init_network (void)
|
|
|
|
gconfig.ipsecsaref=0;
|
|
}
|
|
-
|
|
- arg=1;
|
|
- if(setsockopt(server_socket, IPPROTO_IP, IP_PKTINFO, (char*)&arg, sizeof(arg)) != 0) {
|
|
- l2tp_log(LOG_CRIT, "setsockopt IP_PKTINFO: %s\n", strerror(errno));
|
|
- }
|
|
#else
|
|
{
|
|
l2tp_log(LOG_INFO, "No attempt being made to use IPsec SAref's since we're not on a Linux machine.\n");
|
|
}
|
|
-
|
|
+#endif
|
|
+#ifdef IP_PKTINFO
|
|
+ arg=1;
|
|
+ if(setsockopt(server_socket, IPPROTO_IP, IP_PKTINFO, (char*)&arg, sizeof(arg)) != 0) {
|
|
+ l2tp_log(LOG_CRIT, "setsockopt IP_PKTINFO: %s\n", strerror(errno));
|
|
+ }
|
|
#endif
|
|
|
|
/* turn off UDP checksums */
|
|
+#ifdef SO_NO_CHECK
|
|
arg=1;
|
|
if (setsockopt(server_socket, SOL_SOCKET, SO_NO_CHECK , (void*)&arg,
|
|
sizeof(arg)) ==-1) {
|
|
l2tp_log(LOG_INFO, "unable to turn off UDP checksums");
|
|
}
|
|
+#endif
|
|
|
|
#ifdef USE_KERNEL
|
|
if (gconfig.forceuserspace)
|
|
@@ -135,7 +137,7 @@ int init_network (void)
|
|
return 0;
|
|
}
|
|
|
|
-inline void extract (void *buf, int *tunnel, int *call)
|
|
+static inline void extract (void *buf, int *tunnel, int *call)
|
|
{
|
|
/*
|
|
* Extract the tunnel and call #'s, and fix the order of the
|
|
@@ -155,15 +157,13 @@ inline void extract (void *buf, int *tun
|
|
}
|
|
}
|
|
|
|
-inline void fix_hdr (void *buf)
|
|
+static inline void fix_hdr (void *buf)
|
|
{
|
|
/*
|
|
* Fix the byte order of the header
|
|
*/
|
|
-
|
|
- struct payload_hdr *p = (struct payload_hdr *) buf;
|
|
- _u16 ver = ntohs (p->ver);
|
|
- if (CTBIT (p->ver))
|
|
+ _u16 ver = ntohs (*(_u16 *)buf);
|
|
+ if (CTBIT (ver))
|
|
{
|
|
/*
|
|
* Control headers are always
|
|
@@ -280,12 +280,18 @@ void control_xmit (void *b)
|
|
void udp_xmit (struct buffer *buf, struct tunnel *t)
|
|
{
|
|
struct cmsghdr *cmsg;
|
|
- char cbuf[CMSG_SPACE(sizeof (unsigned int) + sizeof (struct in_pktinfo))];
|
|
+ char cbuf[CMSG_SPACE(sizeof (unsigned int)
|
|
+#ifdef IP_PKTINFO
|
|
+ + sizeof (struct in_pktinfo)
|
|
+#endif
|
|
+ )];
|
|
unsigned int *refp;
|
|
struct msghdr msgh;
|
|
int err;
|
|
struct iovec iov;
|
|
+#ifdef IP_PKTINFO
|
|
struct in_pktinfo *pktinfo;
|
|
+#endif
|
|
int finallen;
|
|
|
|
/*
|
|
@@ -312,7 +318,7 @@ void udp_xmit (struct buffer *buf, struc
|
|
|
|
finallen = cmsg->cmsg_len;
|
|
}
|
|
-
|
|
+#ifdef IP_PKTINFO
|
|
if (t->my_addr.ipi_addr.s_addr){
|
|
|
|
if ( ! cmsg) {
|
|
@@ -331,7 +337,9 @@ void udp_xmit (struct buffer *buf, struc
|
|
|
|
finallen += cmsg->cmsg_len;
|
|
}
|
|
-
|
|
+#endif
|
|
+ if (finallen == 0)
|
|
+ msgh.msg_control = NULL;
|
|
msgh.msg_controllen = finallen;
|
|
|
|
iov.iov_base = buf->start;
|
|
@@ -426,7 +434,9 @@ void network_thread ()
|
|
* our network socket. Control handling is no longer done here.
|
|
*/
|
|
struct sockaddr_in from;
|
|
+#ifdef IP_PKTINFO
|
|
struct in_pktinfo to;
|
|
+#endif
|
|
unsigned int fromlen;
|
|
int tunnel, call; /* Tunnel and call */
|
|
int recvsize; /* Length of data received */
|
|
@@ -506,7 +516,9 @@ void network_thread ()
|
|
buf->len -= PAYLOAD_BUF;
|
|
|
|
memset(&from, 0, sizeof(from));
|
|
+#ifdef IP_PKTINFO
|
|
memset(&to, 0, sizeof(to));
|
|
+#endif
|
|
|
|
fromlen = sizeof(from);
|
|
|
|
@@ -557,13 +569,16 @@ void network_thread ()
|
|
for (cmsg = CMSG_FIRSTHDR(&msgh);
|
|
cmsg != NULL;
|
|
cmsg = CMSG_NXTHDR(&msgh,cmsg)) {
|
|
+#ifdef IP_PKTINFO
|
|
/* extract destination(our) addr */
|
|
if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
|
|
struct in_pktinfo* pktInfo = ((struct in_pktinfo*)CMSG_DATA(cmsg));
|
|
to = *pktInfo;
|
|
+ continue;
|
|
}
|
|
+#endif
|
|
/* extract IPsec info out */
|
|
- else if (gconfig.ipsecsaref && cmsg->cmsg_level == IPPROTO_IP
|
|
+ if (gconfig.ipsecsaref && cmsg->cmsg_level == IPPROTO_IP
|
|
&& cmsg->cmsg_type == gconfig.sarefnum) {
|
|
unsigned int *refp;
|
|
|
|
@@ -592,6 +607,8 @@ void network_thread ()
|
|
|
|
if (gconfig.packet_dump)
|
|
{
|
|
+ struct payload_hdr *p = (struct payload_hdr *) buf->start;
|
|
+ l2tp_log(LOG_DEBUG, "ver = 0x%x\n", p->ver);
|
|
do_packet_dump (buf);
|
|
}
|
|
if (!
|
|
@@ -627,9 +644,11 @@ void network_thread ()
|
|
}
|
|
else
|
|
{
|
|
+#ifdef IP_PKTINFO
|
|
if (c->container) {
|
|
c->container->my_addr = to;
|
|
}
|
|
+#endif
|
|
|
|
buf->peer = from;
|
|
/* Handle the packet */
|