summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/in.h1
-rw-r--r--sys/netinet/in_pcb.h1
-rw-r--r--sys/netinet/ip_output.c14
-rw-r--r--sys/netinet/raw_ip.c3
-rw-r--r--sys/netinet/tcp_input.c5
-rw-r--r--sys/netinet/tcp_reass.c5
-rw-r--r--sys/netinet/udp_usrreq.c3
7 files changed, 32 insertions, 0 deletions
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index 45c269c..f006ae3 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -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
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 99e12ad..3d267ae 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -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 {
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 90c50a3..b292d80 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -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:
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 3d2c6d2..8a128eb 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -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;
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index c86a3ec..369315d 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -740,6 +740,11 @@ findpcb:
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
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index c86a3ec..369315d 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -740,6 +740,11 @@ findpcb:
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
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 0ffb004..6de2d7b 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -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);
OpenPOWER on IntegriCloud