summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/raw_ip6.c
diff options
context:
space:
mode:
authoranchie <anchie@FreeBSD.org>2010-08-19 11:31:03 +0000
committeranchie <anchie@FreeBSD.org>2010-08-19 11:31:03 +0000
commitc6c2feb282a53da0c88c776fa754d0952cc04718 (patch)
treef2b6c6d34ce5b086e7277b0987add39e98fc6aad /sys/netinet6/raw_ip6.c
parent3a511a56fe7b6da1c2a173ffdbc92e9bc8da612a (diff)
downloadFreeBSD-src-c6c2feb282a53da0c88c776fa754d0952cc04718.zip
FreeBSD-src-c6c2feb282a53da0c88c776fa754d0952cc04718.tar.gz
MFp4: anchie_soc2009 branch:
Add kernel side support for Secure Neighbor Discovery (SeND), RFC 3971. The implementation consists of a kernel module that gets packets from the nd6 code, sends them to user space on a dedicated socket and reinjects them back for further processing. Hooks are used from nd6 code paths to divert relevant packets to the send implementation for processing in user space. The hooks are only triggered if the send module is loaded. In case no user space application is connected to the send socket, processing continues normaly as if the module would not be loaded. Unloading the module is not possible at this time due to missing nd6 locking. The native SeND socket is similar to a raw IPv6 socket but with its own, internal pseudo-protocol. Approved by: bz (mentor)
Diffstat (limited to 'sys/netinet6/raw_ip6.c')
-rw-r--r--sys/netinet6/raw_ip6.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 9365360..0e5e8e0 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -92,6 +92,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/icmp6.h>
#include <netinet/ip6.h>
+#include <netinet/ip_var.h>
#include <netinet6/ip6protosw.h>
#include <netinet6/ip6_mroute.h>
#include <netinet6/in6_pcb.h>
@@ -99,6 +100,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/nd6.h>
#include <netinet6/raw_ip6.h>
#include <netinet6/scope6_var.h>
+#include <netinet6/send.h>
#ifdef IPSEC
#include <netipsec/ipsec.h>
@@ -390,6 +392,7 @@ rip6_output(m, va_alist)
#endif
{
struct mbuf *control;
+ struct m_tag *mtag;
struct socket *so;
struct sockaddr_in6 *dstsock;
struct in6_addr *dst;
@@ -532,6 +535,23 @@ rip6_output(m, va_alist)
*p = in6_cksum(m, ip6->ip6_nxt, sizeof(*ip6), plen);
}
+ /*
+ * Send RA/RS messages to user land for protection, before sending
+ * them to rtadvd/rtsol.
+ */
+ if ((send_sendso_input_hook != NULL) &&
+ so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
+ switch (type) {
+ case ND_ROUTER_ADVERT:
+ case ND_ROUTER_SOLICIT:
+ mtag = m_tag_get(PACKET_TAG_ND_OUTGOING,
+ sizeof(unsigned short), M_NOWAIT);
+ if (mtag == NULL)
+ goto bad;
+ m_tag_prepend(m, mtag);
+ }
+ }
+
error = ip6_output(m, optp, NULL, 0, in6p->in6p_moptions, &oifp, in6p);
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
if (oifp)
OpenPOWER on IntegriCloud