Add socketoption IP_MINTTL. May be used to set the minimum acceptable

TTL a packet must have when received on a socket.  All packets with a
lower TTL are silently dropped.  Works on already connected/connecting
and listening sockets for RAW/UDP/TCP.

This option is only really useful when set to 255 preventing packets
from outside the directly connected networks reaching local listeners
on sockets.

Allows userland implementation of 'The Generalized TTL Security Mechanism
(GTSM)' according to RFC3682.  Examples of such use include the Cisco IOS
BGP implementation command "neighbor ttl-security".

MFC after:	2 weeks
Sponsored by:	TCP/IP Optimization Fundraise 2005
This commit is contained in:
andre 2005-08-22 16:13:08 +00:00
parent ef76245e90
commit 573a9535a8
7 changed files with 32 additions and 0 deletions

View File

@ -415,6 +415,7 @@ __END_DECLS
#define IP_DUMMYNET_GET 64 /* get entire dummynet pipes */
#define IP_RECVTTL 65 /* bool; receive IP TTL w/dgram */
#define IP_MINTTL 66 /* minimum TTL for packet or drop */
/*
* Defaults and limits for options

View File

@ -133,6 +133,7 @@ struct inpcb {
#define INP_ONESBCAST 0x10 /* send all-ones broadcast */
u_char inp_ip_ttl; /* time to live proto */
u_char inp_ip_p; /* protocol proto */
u_char inp_ip_minttl; /* minimum TTL or drop */
/* protocol dependent part; options */
struct {

View File

@ -1189,6 +1189,7 @@ ip_ctloutput(so, sopt)
case IP_TOS:
case IP_TTL:
case IP_MINTTL:
case IP_RECVOPTS:
case IP_RECVRETOPTS:
case IP_RECVDSTADDR:
@ -1209,6 +1210,14 @@ ip_ctloutput(so, sopt)
case IP_TTL:
inp->inp_ip_ttl = optval;
break;
case IP_MINTTL:
if (optval > 0 && optval <= MAXTTL)
inp->inp_ip_minttl = optval;
else
error = EINVAL;
break;
#define OPTSET(bit) do { \
INP_LOCK(inp); \
if (optval) \
@ -1333,6 +1342,7 @@ ip_ctloutput(so, sopt)
case IP_TOS:
case IP_TTL:
case IP_MINTTL:
case IP_RECVOPTS:
case IP_RECVRETOPTS:
case IP_RECVDSTADDR:
@ -1351,6 +1361,10 @@ ip_ctloutput(so, sopt)
optval = inp->inp_ip_ttl;
break;
case IP_MINTTL:
optval = inp->inp_ip_minttl;
break;
#define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0)
case IP_RECVOPTS:

View File

@ -157,6 +157,9 @@ raw_append(struct inpcb *last, struct ip *ip, struct mbuf *n)
if (!policyfail && mac_check_inpcb_deliver(last, n) != 0)
policyfail = 1;
#endif
/* Check the minimum TTL for socket. */
if (last->inp_ip_minttl && last->inp_ip_minttl > ip->ip_ttl)
policyfail = 1;
if (!policyfail) {
struct mbuf *opts = NULL;
struct socket *so;

View File

@ -740,6 +740,11 @@ tcp_input(m, off0)
goto dropwithreset;
}
INP_LOCK(inp);
/* Check the minimum TTL for socket. */
if (inp->inp_ip_minttl && inp->inp_ip_minttl > ip->ip_ttl)
goto drop;
if (inp->inp_vflag & INP_TIMEWAIT) {
/*
* The only option of relevance is TOF_CC, and only if

View File

@ -740,6 +740,11 @@ tcp_input(m, off0)
goto dropwithreset;
}
INP_LOCK(inp);
/* Check the minimum TTL for socket. */
if (inp->inp_ip_minttl && inp->inp_ip_minttl > ip->ip_ttl)
goto drop;
if (inp->inp_vflag & INP_TIMEWAIT) {
/*
* The only option of relevance is TOF_CC, and only if

View File

@ -384,6 +384,9 @@ udp_input(m, off)
return;
}
INP_LOCK(inp);
/* Check the minimum TTL for socket. */
if (inp->inp_ip_minttl && inp->inp_ip_minttl > ip->ip_ttl)
goto badheadlocked;
udp_append(inp, ip, m, iphlen + sizeof(struct udphdr), &udp_in);
INP_UNLOCK(inp);
INP_INFO_RUNLOCK(&udbinfo);