diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2018-01-15 12:25:04 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2018-01-15 12:25:04 +0000 |
commit | d9721719f970f641347ee251416a5bc33649c995 (patch) | |
tree | 34b4239f4953acb4f88efbc982329f45e140f89b /sys/net | |
parent | 9b6840cc9a25ecf972e1509de91743dcd32e674f (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.c | 24 |
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, |