From 4d3ffc9841c030f4d27539993c3c933da4c36179 Mon Sep 17 00:00:00 2001 From: Bill Fenner Date: Tue, 29 Oct 2002 16:46:13 +0000 Subject: [PATCH] Renumber IPPROTO_DIVERT out of the range of valid IP protocol numbers. This allows socket() to return an error when the kernel is not built with IPDIVERT, and doesn't prevent future applications from using the "borrowed" IP protocol number. The sysctl net.inet.raw.olddiverterror controls whether opening a socket with the "borrowed" IP protocol fails with an accompanying kernel printf; this code should last only a couple of releases. Approved by: re --- sys/netinet/in.h | 7 +++++-- sys/netinet/ip_divert.c | 4 ++-- sys/netinet/raw_ip.c | 12 ++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/sys/netinet/in.h b/sys/netinet/in.h index 09fd395f76ef..c974bc561e12 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -236,13 +236,16 @@ __END_DECLS #define IPPROTO_PIM 103 /* Protocol Independent Mcast */ #define IPPROTO_PGM 113 /* PGM */ /* 255: Reserved */ -/* BSD Private, local use, namespace incursion */ -#define IPPROTO_DIVERT 254 /* divert pseudo-protocol */ +/* BSD Private, local use, namespace incursion, no longer used */ +#define IPPROTO_OLD_DIVERT 254 /* OLD divert pseudo-proto */ #define IPPROTO_MAX 256 /* last return value of *_input(), meaning "all job for this pkt is done". */ #define IPPROTO_DONE 257 +/* Only used internally, so can be outside the range of valid IP protocols. */ +#define IPPROTO_DIVERT 258 /* divert pseudo-protocol */ + /* * Local port number conventions: * diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 808819d1f4dd..908273384acc 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -136,8 +136,8 @@ div_init(void) } /* - * IPPROTO_DIVERT is not a real IP protocol; don't allow any packets - * with that protocol number to enter the system from the outside. + * IPPROTO_DIVERT is not in the real IP protocol number space; this + * function should never be called. Just in case, drop any packets. */ void div_input(struct mbuf *m, int off) diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 97dabefcf3e2..f435d97fa1a8 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -493,11 +493,14 @@ rip_ctlinput(cmd, sa, vip) u_long rip_sendspace = RIPSNDQ; u_long rip_recvspace = RIPRCVQ; +int rip_olddiverterror = 1; SYSCTL_INT(_net_inet_raw, OID_AUTO, maxdgram, CTLFLAG_RW, &rip_sendspace, 0, "Maximum outgoing raw IP datagram size"); SYSCTL_INT(_net_inet_raw, OID_AUTO, recvspace, CTLFLAG_RW, &rip_recvspace, 0, "Maximum incoming raw IP datagram size"); +SYSCTL_INT(_net_inet_raw, OID_AUTO, olddiverterror, CTLFLAG_RW, + &rip_olddiverterror, 0, "Return an error when creating an 'old' DIVERT socket"); static int rip_attach(struct socket *so, int proto, struct thread *td) @@ -511,6 +514,15 @@ rip_attach(struct socket *so, int proto, struct thread *td) if (td && (error = suser(td)) != 0) return error; + if (proto >= IPPROTO_MAX || proto < 0) + return EPROTONOSUPPORT; + + /* To be removed before 5.2 */ + if (rip_olddiverterror && proto == IPPROTO_OLD_DIVERT) { + printf("Old IPDIVERT program needs to be recompiled, or new IP proto 254 user needs sysctl net.inet.raw.olddiverterror=0\n"); + return EPROTONOSUPPORT; + } + error = soreserve(so, rip_sendspace, rip_recvspace); if (error) return error;