summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2018-01-15 12:25:04 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2018-01-15 12:25:04 +0000
commitd9721719f970f641347ee251416a5bc33649c995 (patch)
tree34b4239f4953acb4f88efbc982329f45e140f89b /sys/net
parent9b6840cc9a25ecf972e1509de91743dcd32e674f (diff)
When pf(4) forwards incoming packets with route-to or reply-to,
decrement the time-to-live or hop-limit field to prevent routing loops. Sending an ICMP time exceeded error makes traceroute work. For outgoing packets ip_forward() has already done this. OK visa@ sashan@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/pf.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 185d969bc34..fa0a91383d1 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.1055 2018/01/10 13:57:17 bluhm Exp $ */
+/* $OpenBSD: pf.c,v 1.1056 2018/01/15 12:25:03 bluhm Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -5912,6 +5912,17 @@ pf_route(struct pf_pdesc *pd, struct pf_rule *r, struct pf_state *s)
dst->sin_addr = ip->ip_dst;
rtableid = m0->m_pkthdr.ph_rtableid;
+ if (pd->dir == PF_IN) {
+ if (ip->ip_ttl <= IPTTLDEC) {
+ if (r->rt != PF_DUPTO)
+ pf_send_icmp(m0, ICMP_TIMXCEED,
+ ICMP_TIMXCEED_INTRANS, 0,
+ pd->af, r, pd->rdomain);
+ goto bad;
+ }
+ ip->ip_ttl -= IPTTLDEC;
+ }
+
if (s == NULL) {
bzero(sns, sizeof(sns));
if (pf_map_addr(AF_INET, r,
@@ -6054,6 +6065,17 @@ pf_route6(struct pf_pdesc *pd, struct pf_rule *r, struct pf_state *s)
dst->sin6_addr = ip6->ip6_dst;
rtableid = m0->m_pkthdr.ph_rtableid;
+ if (pd->dir == PF_IN) {
+ if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
+ if (r->rt != PF_DUPTO)
+ pf_send_icmp(m0, ICMP6_TIME_EXCEEDED,
+ ICMP6_TIME_EXCEED_TRANSIT, 0,
+ pd->af, r, pd->rdomain);
+ goto bad;
+ }
+ ip6->ip6_hlim -= IPV6_HLIMDEC;
+ }
+
if (s == NULL) {
bzero(sns, sizeof(sns));
if (pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,