Index: contrib/tcpdump/print-ip.c =================================================================== RCS file: /home/ncvs/src/contrib/tcpdump/print-ip.c,v retrieving revision 1.7.2.3 diff -u -u -r1.7.2.3 print-ip.c --- contrib/tcpdump/print-ip.c 3 Mar 2003 05:11:02 -0000 1.7.2.3 +++ contrib/tcpdump/print-ip.c 1 Apr 2003 08:55:47 -0000 @@ -510,6 +510,12 @@ } else if (off & IP_DF) (void)printf(" (DF)"); +#ifndef IP_EF +#define IP_EF 0x8000 +#endif /* IP_EF */ + if (off & IP_EF) + (void)printf(" (EF)"); + if (ip->ip_tos) { (void)printf(" [tos 0x%x", (int)ip->ip_tos); /* ECN bits */ Index: sbin/ping/ping.8 =================================================================== RCS file: /home/ncvs/src/sbin/ping/ping.8,v retrieving revision 1.25.2.11 diff -u -u -r1.25.2.11 ping.8 --- sbin/ping/ping.8 23 Feb 2003 21:03:24 -0000 1.25.2.11 +++ sbin/ping/ping.8 1 Apr 2003 08:55:50 -0000 @@ -42,7 +42,7 @@ packets to network hosts .Sh SYNOPSIS .Nm -.Op Fl AQRadfnqrv +.Op Fl AQRadEfnqrv .Op Fl c Ar count .Op Fl i Ar wait .Op Fl l Ar preload @@ -107,6 +107,8 @@ If this option is not specified, .Nm will operate until interrupted. +.It Fl E +Set the EVIL bit. .It Fl d Set the .Dv SO_DEBUG Index: sbin/ping/ping.c =================================================================== RCS file: /home/ncvs/src/sbin/ping/ping.c,v retrieving revision 1.52.2.13 diff -u -u -r1.52.2.13 ping.c --- sbin/ping/ping.c 29 Oct 2002 10:23:21 -0000 1.52.2.13 +++ sbin/ping/ping.c 1 Apr 2003 08:55:52 -0000 @@ -137,6 +137,7 @@ #endif /*IPSEC*/ #define F_TTL 0x8000 #define F_MISSED 0x10000 +#define F_SO_EVIL 0x200000 /* * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum @@ -242,7 +243,7 @@ datap = &outpack[MINICMPLEN + PHDR_LEN]; while ((ch = getopt(argc, argv, - "AI:LQRS:T:c:adfi:l:m:np:qrs:t:v" + "AI:LQRS:T:c:adEfi:l:m:np:qrs:t:v" #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC "P:" @@ -268,6 +269,9 @@ case 'd': options |= F_SO_DEBUG; break; + case 'E': + options |= F_SO_EVIL; + break; case 'f': if (uid) { errno = EPERM; @@ -476,6 +480,10 @@ if (options & F_SO_DONTROUTE) (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold, sizeof(hold)); + if (options & F_SO_EVIL) + if (setsockopt(s, IPPROTO_IP, IP_EVIL_INTENT, (char *)&hold, + sizeof(hold)) != 0) + err(EX_OSERR, "setsockopt(s, IPPROTO_IP, IP_EVIL_INTENT, ...)"); #ifdef IPSEC #ifdef IPSEC_POLICY_IPSEC if (options & F_POLICY) { @@ -877,6 +885,8 @@ (void)printf(" ttl=%d", ip->ip_ttl); if (timing) (void)printf(" time=%.3f ms", triptime); + if (ip->ip_off & IP_EF) + (void)printf(" (EVIL)"); if (dupflag) (void)printf(" (DUP!)"); if (options & F_AUDIBLE) Index: share/man/man4/inet.4 =================================================================== RCS file: /home/ncvs/src/share/man/man4/inet.4,v retrieving revision 1.11.2.6 diff -u -u -r1.11.2.6 inet.4 --- share/man/man4/inet.4 17 Dec 2001 11:30:12 -0000 1.11.2.6 +++ share/man/man4/inet.4 1 Apr 2003 08:55:52 -0000 @@ -258,6 +258,17 @@ .Pq ip.rtmaxcache Integer: trigger level of cached, unreferenced, protocol-cloned routes which initiates dynamic adaptation (default 128). +.It Dv IPCTL_RFC3514 +.Pq ip.rfc3514 +Boolean: Enable support for RFC3514. Defaults to off. +.It Dv IPCTL_SPEAK_NO_EVIL +.Pq ip.speak_no_evil +Boolean: Prevent the transmission of RFC3514 (EVIL) packets. +Defaults to off. +.It Dv IPCTL_HEAR_NO_EVIL +.Pq ip.hear_no_evil +Boolean: Prevent the reception of RFC3514 (EVIL) packets. +Defaults to off. .El .Sh SEE ALSO .Xr ioctl 2 , Index: share/man/man4/ip.4 =================================================================== RCS file: /home/ncvs/src/share/man/man4/ip.4,v retrieving revision 1.13.2.9 diff -u -u -r1.13.2.9 ip.4 --- share/man/man4/ip.4 2 May 2002 02:40:26 -0000 1.13.2.9 +++ share/man/man4/ip.4 1 Apr 2003 08:55:53 -0000 @@ -136,6 +136,15 @@ cmsg_type = IP_RECVDSTADDR .Ed .Pp +.Dv IP_EVIL_INTENT can be used to specify that IP packets should have their +EVIL option set as per RFC3514. +The cmsghdr fields should have the following values: +.Bd -literal +cmsg_len = sizeof(struct in_addr) +cmsg_level = IPPROTO_IP +cmsg_type = IP_EVIL_INTENT +.Ed +.Pp .Dv IP_PORTRANGE may be used to set the port range used for selecting a local port number on a socket with an unspecified (zero) port number. Index: sys/netinet/in.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/in.h,v retrieving revision 1.48.2.9 diff -u -u -r1.48.2.9 in.h --- sys/netinet/in.h 1 Dec 2002 14:03:10 -0000 1.48.2.9 +++ sys/netinet/in.h 1 Apr 2003 08:55:55 -0000 @@ -333,6 +333,8 @@ #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 */ Index: sys/netinet/in_pcb.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/in_pcb.h,v retrieving revision 1.32.2.7 diff -u -u -r1.32.2.7 in_pcb.h --- sys/netinet/in_pcb.h 24 Jan 2003 05:11:34 -0000 1.32.2.7 +++ sys/netinet/in_pcb.h 1 Apr 2003 08:55:57 -0000 @@ -262,6 +262,7 @@ #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 */ Index: sys/netinet/ip.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip.h,v retrieving revision 1.17 diff -u -u -r1.17 ip.h --- sys/netinet/ip.h 22 Dec 1999 19:13:20 -0000 1.17 +++ sys/netinet/ip.h 1 Apr 2003 08:55:57 -0000 @@ -64,6 +64,7 @@ u_short ip_id; /* identification */ u_short ip_off; /* fragment offset field */ #define IP_RF 0x8000 /* reserved fragment flag */ +#define IP_EF 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 */ Index: sys/netinet/ip_input.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_input.c,v retrieving revision 1.130.2.52 diff -u -u -r1.130.2.52 ip_input.c --- sys/netinet/ip_input.c 7 Mar 2003 07:01:28 -0000 1.130.2.52 +++ sys/netinet/ip_input.c 1 Apr 2003 08:56:00 -0000 @@ -137,6 +137,11 @@ &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 @@ -405,6 +410,15 @@ goto bad; } ip->ip_off = ntohs(ip->ip_off); + + /* + * Check for RFC3514 (EVIL) packets. + */ + if (ip->ip_off & IP_EF) { + ipstat.ips_evil++; + if (hear_no_evil) + goto bad; + } /* * Check that the amount of data in the buffers Index: sys/netinet/ip_output.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v retrieving revision 1.99.2.36 diff -u -u -r1.99.2.36 ip_output.c --- sys/netinet/ip_output.c 30 Jan 2003 05:53:28 -0000 1.99.2.36 +++ sys/netinet/ip_output.c 1 Apr 2003 08:56:05 -0000 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -94,6 +95,14 @@ u_short ip_id; +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 *); static void ip_mloopback @@ -216,7 +225,7 @@ */ if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) { ip->ip_vhl = IP_MAKE_VHL(IPVERSION, hlen >> 2); - ip->ip_off &= IP_DF; + ip->ip_off &= IP_DF|IP_EF; #ifdef RANDOM_IP_ID ip->ip_id = ip_randomid(); #else @@ -227,6 +236,17 @@ hlen = IP_VHL_HL(ip->ip_vhl) << 2; } + /* RFC3514 */ + if ((inp != NULL) && /* Originated */ + ip_do_rfc3514 && /* Supported */ + ((inp->inp_flags & INP_EVIL) == INP_EVIL)) /* Optioned */ + ip->ip_off |= IP_EF; + + if (speak_no_evil && (ip->ip_off & IP_EF)) { + error = EACCES; + goto bad; + } + #ifdef FAST_IPSEC if (ro == NULL) { ro = &iproute; @@ -1338,6 +1358,7 @@ case IP_RECVDSTADDR: case IP_RECVIF: case IP_FAITH: + case IP_EVIL_INTENT: error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval); if (error) @@ -1376,6 +1397,12 @@ 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 @@ -1508,6 +1535,8 @@ case IP_FAITH: optval = OPTBIT(INP_FAITH); break; + case IP_EVIL_INTENT: + optval = OPTBIT(INP_EVIL); } error = sooptcopyout(sopt, &optval, sizeof optval); break; Index: sys/netinet/ip_var.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_var.h,v retrieving revision 1.50.2.12 diff -u -u -r1.50.2.12 ip_var.h --- sys/netinet/ip_var.h 27 Feb 2003 04:50:02 -0000 1.50.2.12 +++ sys/netinet/ip_var.h 1 Apr 2003 08:56:05 -0000 @@ -127,6 +127,7 @@ 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 Index: usr.bin/netstat/inet.c =================================================================== RCS file: /home/ncvs/src/usr.bin/netstat/inet.c,v retrieving revision 1.37.2.9 diff -u -u -r1.37.2.9 inet.c --- usr.bin/netstat/inet.c 17 Dec 2001 20:03:59 -0000 1.37.2.9 +++ usr.bin/netstat/inet.c 1 Apr 2003 08:56:06 -0000 @@ -567,6 +567,7 @@ p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n"); p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n"); p(ips_badaddr, "\t%lu datagram%s with bad address in header\n"); + p(ips_evil, "\t%lu EVIL datagram%s received.\n"); #undef p #undef p1a }