summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormdodd <mdodd@FreeBSD.org>2003-04-01 08:21:44 +0000
committermdodd <mdodd@FreeBSD.org>2003-04-01 08:21:44 +0000
commite72fdee732ab55fc784034c81ccedda4b5279816 (patch)
treef90a5d7ffe2a0b6602c7942defa8707719f90a9c /sys
parent0bafba46a2e8ee2d4fd220f149d08306f11d0f4d (diff)
downloadFreeBSD-src-e72fdee732ab55fc784034c81ccedda4b5279816.zip
FreeBSD-src-e72fdee732ab55fc784034c81ccedda4b5279816.tar.gz
Implement support for RFC 3514 (The Security Flag in the IPv4 Header).
(See: ftp://ftp.rfc-editor.org/in-notes/rfc3514.txt) This fulfills the host requirements for userland support by way of the setsockopt() IP_EVIL_INTENT message. There are three sysctl tunables provided to govern system behavior. net.inet.ip.rfc3514: Enables support for rfc3514. As this is an Informational RFC and support is not yet widespread this option is disabled by default. net.inet.ip.hear_no_evil If set the host will discard all received evil packets. net.inet.ip.speak_no_evil If set the host will discard all transmitted evil packets. The IP statistics counter 'ips_evil' (available via 'netstat') provides information on the number of 'evil' packets recieved. For reference, the '-E' option to 'ping' has been provided to demonstrate and test the implementation.
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/in.h2
-rw-r--r--sys/netinet/in_pcb.h1
-rw-r--r--sys/netinet/ip.h1
-rw-r--r--sys/netinet/ip_input.c14
-rw-r--r--sys/netinet/ip_output.c29
-rw-r--r--sys/netinet/ip_var.h1
6 files changed, 47 insertions, 1 deletions
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index 83eeae7..49f83e5 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -399,6 +399,8 @@ __END_DECLS
#define IP_DUMMYNET_FLUSH 62 /* flush dummynet */
#define IP_DUMMYNET_GET 64 /* get entire dummynet pipes */
+#define IP_EVIL_INTENT 65 /* RFC3514 */
+
/*
* Defaults and limits for options
*/
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index efb7862..eb02c6e 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -276,6 +276,7 @@ struct inpcbinfo { /* XXX documentation, prefixes */
#define INP_RECVIF 0x80 /* receive incoming interface */
#define INP_MTUDISC 0x100 /* user can do MTU discovery */
#define INP_FAITH 0x200 /* accept FAITH'ed connections */
+#define INP_EVIL 0x400 /* Packet has evil intentions */
#define IN6P_IPV6_V6ONLY 0x008000 /* restrict AF_INET6 socket for v6 */
diff --git a/sys/netinet/ip.h b/sys/netinet/ip.h
index 24f66ce..4b3c097 100644
--- a/sys/netinet/ip.h
+++ b/sys/netinet/ip.h
@@ -62,6 +62,7 @@ struct ip {
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
+#define IP_EVIL 0x8000 /* packet is evil */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index e26cc8d..8b130f5 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -134,6 +134,11 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, sendsourcequench, CTLFLAG_RW,
&ip_sendsourcequench, 0,
"Enable the transmission of source quench packets");
+static int hear_no_evil = 0;
+SYSCTL_INT(_net_inet_ip, OID_AUTO, hear_no_evil, CTLFLAG_RW,
+ &hear_no_evil, 0,
+ "Drop all received EVIL packets.");
+
/*
* XXX - Setting ip_checkinterface mostly implements the receive side of
* the Strong ES model described in RFC 1122, but since the routing table
@@ -407,6 +412,15 @@ ip_input(struct mbuf *m)
ip->ip_off = ntohs(ip->ip_off);
/*
+ * Check for RFC3514 (EVIL) packets.
+ */
+ if (ip->ip_off & IP_EVIL) {
+ ipstat.ips_evil++;
+ if (hear_no_evil)
+ goto bad;
+ }
+
+ /*
* Check that the amount of data in the buffers
* is as at least much as the IP header would have us expect.
* Trim mbufs if longer than we expect.
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index c00ac4c..822ca89 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -101,6 +101,13 @@ int mbuf_frag_size = 0;
SYSCTL_INT(_net_inet_ip, OID_AUTO, mbuf_frag_size, CTLFLAG_RW,
&mbuf_frag_size, 0, "Fragment outgoing mbufs to this size");
#endif
+static int ip_do_rfc3514 = 0;
+SYSCTL_INT(_net_inet_ip, OID_AUTO, rfc3514, CTLFLAG_RW,
+ &ip_do_rfc3514, 0, "IPv4 Header Security Flag Support");
+
+static int speak_no_evil = 0;
+SYSCTL_INT(_net_inet_ip, OID_AUTO, speak_no_evil, CTLFLAG_RW,
+ &speak_no_evil, 0, "Drop all EVIL packets before output.");
static struct mbuf *ip_insertoptions(struct mbuf *, struct mbuf *, int *);
static struct ifnet *ip_multicast_if(struct in_addr *, int *);
@@ -228,7 +235,7 @@ ip_output(m0, opt, ro, flags, imo, inp)
if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
ip->ip_v = IPVERSION;
ip->ip_hl = hlen >> 2;
- ip->ip_off &= IP_DF;
+ ip->ip_off &= IP_DF|IP_EVIL;
#ifdef RANDOM_IP_ID
ip->ip_id = ip_randomid();
#else
@@ -239,6 +246,17 @@ ip_output(m0, opt, ro, flags, imo, inp)
hlen = ip->ip_hl << 2;
}
+ /* RFC3514 */
+ if ((inp != NULL) && /* Originated */
+ ip_do_rfc3514 && /* Supported */
+ ((inp->inp_flags & INP_EVIL) == INP_EVIL)) /* Optioned */
+ ip->ip_off |= IP_EVIL;
+
+ if (speak_no_evil && (ip->ip_off & IP_EVIL)) {
+ error = EACCES;
+ goto bad;
+ }
+
#ifdef FAST_IPSEC
if (ro == NULL) {
ro = &iproute;
@@ -1426,6 +1444,7 @@ ip_ctloutput(so, sopt)
case IP_RECVDSTADDR:
case IP_RECVIF:
case IP_FAITH:
+ case IP_EVIL_INTENT:
error = sooptcopyin(sopt, &optval, sizeof optval,
sizeof optval);
if (error)
@@ -1464,6 +1483,12 @@ ip_ctloutput(so, sopt)
case IP_FAITH:
OPTSET(INP_FAITH);
break;
+ case IP_EVIL_INTENT:
+ if (ip_do_rfc3514) {
+ OPTSET(INP_EVIL);
+ } else
+ error = EINVAL;
+ break;
}
break;
#undef OPTSET
@@ -1596,6 +1621,8 @@ ip_ctloutput(so, sopt)
case IP_FAITH:
optval = OPTBIT(INP_FAITH);
break;
+ case IP_EVIL:
+ optval = OPTBIT(INP_EVIL);
}
error = sooptcopyout(sopt, &optval, sizeof optval);
break;
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index c8df2e6..4e9907b 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -132,6 +132,7 @@ struct ipstat {
u_long ips_notmember; /* multicasts for unregistered grps */
u_long ips_nogif; /* no match gif found */
u_long ips_badaddr; /* invalid address on header */
+ u_long ips_evil; /* EVIL packets received */
};
#ifdef _KERNEL
OpenPOWER on IntegriCloud