summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryasuoka <yasuoka@openbsd.org>2010-01-12 23:33:24 +0000
committeryasuoka <yasuoka@openbsd.org>2010-01-12 23:33:24 +0000
commit825b2eb77a6ca02f3db30b145bce8ee6e18d04d2 (patch)
treebcec4a53d499e8b307ba34646ac2ffb35e666433
parentwhen generating rdr rules, ensure the nat address is PF_ADDR_NONE to avoid (diff)
downloadwireguard-openbsd-825b2eb77a6ca02f3db30b145bce8ee6e18d04d2.tar.xz
wireguard-openbsd-825b2eb77a6ca02f3db30b145bce8ee6e18d04d2.zip
Add input and user protocol hook to handle GRE packets by pipex.
ok @dlg
-rw-r--r--sys/netinet/in_proto.c4
-rw-r--r--sys/netinet/ip_gre.c56
-rw-r--r--sys/netinet/ip_gre.h3
3 files changed, 59 insertions, 4 deletions
diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index c90b80afa61..f30b585dc4a 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_proto.c,v 1.51 2009/10/04 16:08:37 michele Exp $ */
+/* $OpenBSD: in_proto.c,v 1.52 2010/01/12 23:33:24 yasuoka Exp $ */
/* $NetBSD: in_proto.c,v 1.14 1996/02/18 18:58:32 christos Exp $ */
/*
@@ -268,7 +268,7 @@ struct protosw inetsw[] = {
#if NGRE > 0
{ SOCK_RAW, &inetdomain, IPPROTO_GRE, PR_ATOMIC|PR_ADDR,
gre_input, rip_output, 0, rip_ctloutput,
- rip_usrreq,
+ gre_usrreq,
0, 0, 0, 0, gre_sysctl
},
{ SOCK_RAW, &inetdomain, IPPROTO_MOBILE, PR_ATOMIC|PR_ADDR,
diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c
index 80bc7f8e879..4309641dc0c 100644
--- a/sys/netinet/ip_gre.c
+++ b/sys/netinet/ip_gre.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_gre.c,v 1.34 2009/11/21 14:08:14 claudio Exp $ */
+/* $OpenBSD: ip_gre.c,v 1.35 2010/01/12 23:33:24 yasuoka Exp $ */
/* $NetBSD: ip_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */
/*
@@ -43,7 +43,9 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
+#include <sys/protosw.h>
#include <sys/socket.h>
+#include <sys/socketvar.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/netisr.h>
@@ -58,6 +60,7 @@
#include <netinet/ip_var.h>
#include <netinet/ip_gre.h>
#include <netinet/if_ether.h>
+#include <netinet/in_pcb.h>
#else
#error "ip_gre used without inet"
#endif
@@ -75,6 +78,10 @@
#include <net/pfvar.h>
#endif
+#ifdef PIPEX
+#include <net/pipex.h>
+#endif
+
/* Needs IP headers. */
#include <net/if_gre.h>
@@ -226,6 +233,17 @@ gre_input(struct mbuf *m, ...)
return;
}
+#ifdef PIPEX
+ {
+ struct pipex_session *session;
+
+ if ((session = pipex_pptp_lookup_session(m)) != NULL) {
+ if (pipex_pptp_input(m, session) == NULL)
+ return;
+ }
+ }
+#endif
+
ret = gre_input2(m, hlen, IPPROTO_GRE);
/*
* ret == 0: packet not processed, but input from here
@@ -400,4 +418,40 @@ ipmobile_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
}
/* NOTREACHED */
}
+
+int
+gre_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control, struct proc *p)
+{
+#ifdef PIPEX
+ if (req == PRU_SEND) {
+ int s;
+ struct inpcb *inp;
+ struct sockaddr_in *sin4;
+ struct in_addr *ina_dst;
+ struct pipex_session *session;
+
+ s = splsoftnet();
+ ina_dst = NULL;
+ if ((so->so_state & SS_ISCONNECTED) != 0) {
+ inp = sotoinpcb(so);
+ if (inp)
+ ina_dst = &inp->inp_laddr;
+ } else if (nam) {
+ sin4 = mtod(nam, struct sockaddr_in *);
+ if (nam->m_len == sizeof(struct sockaddr_in) &&
+ sin4->sin_family == AF_INET)
+ ina_dst = &sin4->sin_addr;
+ }
+ if (ina_dst != NULL &&
+ (session = pipex_pptp_userland_lookup_session(m, *ina_dst)))
+ m = pipex_pptp_userland_output(m, session);
+ splx(s);
+
+ if (m == NULL)
+ return (ENOMEM);
+ }
+#endif
+ return rip_usrreq(so, req, m, nam, control, p);
+}
#endif /* if NGRE > 0 */
diff --git a/sys/netinet/ip_gre.h b/sys/netinet/ip_gre.h
index 6da3f488669..e91845647a8 100644
--- a/sys/netinet/ip_gre.h
+++ b/sys/netinet/ip_gre.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_gre.h,v 1.8 2008/06/26 05:42:20 ray Exp $ */
+/* $OpenBSD: ip_gre.h,v 1.9 2010/01/12 23:33:24 yasuoka Exp $ */
/* $NetBSD: ip_gre.h,v 1.3 1998/10/07 23:33:02 thorpej Exp $ */
/*
@@ -69,6 +69,7 @@ void gre_mobile_input(struct mbuf *, ...);
int ipmobile_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int gre_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+int gre_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
#endif /* _KERNEL */
#endif /* _NETINET_IP_GRE_H_ */