diff options
author | yar <yar@FreeBSD.org> | 2001-12-29 09:24:18 +0000 |
---|---|---|
committer | yar <yar@FreeBSD.org> | 2001-12-29 09:24:18 +0000 |
commit | 11da1a2ed8b463e093c680c35028445124122f0c (patch) | |
tree | 3ef9bbfd815517e4c0297f1ea6c59d5190effd51 /sys/netinet/ip_input.c | |
parent | 734a071e5d7f49ac2440eb740f5df6c459da6796 (diff) | |
download | FreeBSD-src-11da1a2ed8b463e093c680c35028445124122f0c.zip FreeBSD-src-11da1a2ed8b463e093c680c35028445124122f0c.tar.gz |
Don't reveal a router in the IPSTEALTH mode through IP options.
The following steps are involved:
a) the IP options related to routing (LSRR and SSRR) are processed
as though the router were a host,
b) the other IP options are processed as usual only if the packet
is destined for the router; otherwise they are ignored.
PR: kern/23123
Discussed in: freebsd-hackers
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r-- | sys/netinet/ip_input.c | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 91ed845..c75cd1b 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -211,7 +211,7 @@ static struct ip_srcrt { struct sockaddr_in *ip_fw_fwd_addr; static void save_rte __P((u_char *, struct in_addr)); -static int ip_dooptions __P((struct mbuf *)); +static int ip_dooptions __P((struct mbuf *, int)); static void ip_forward __P((struct mbuf *, int)); static void ip_freef __P((struct ipqhead *, struct ipq *)); #ifdef IPDIVERT @@ -500,7 +500,7 @@ pass: * to be sent and the original packet to be freed). */ ip_nhops = 0; /* for source routed packets */ - if (hlen > sizeof (struct ip) && ip_dooptions(m)) { + if (hlen > sizeof (struct ip) && ip_dooptions(m, 0)) { #ifdef IPFIREWALL_FORWARD ip_fw_fwd_addr = NULL; #endif @@ -658,6 +658,19 @@ pass: return; ours: +#ifdef IPSTEALTH + /* + * IPSTEALTH: Process non-routing options only + * if the packet is destined for us. + */ + if (ipstealth && hlen > sizeof (struct ip) && ip_dooptions(m, 1)) { +#ifdef IPFIREWALL_FORWARD + ip_fw_fwd_addr = NULL; +#endif + return; + } +#endif /* IPSTEALTH */ + /* Count the packet in the ip address stats */ if (ia != NULL) { ia->ia_ifa.if_ipackets++; @@ -1151,12 +1164,18 @@ ip_drain() * Do option processing on a datagram, * possibly discarding it if bad options are encountered, * or forwarding it if source-routed. + * The pass argument is used when operating in the IPSTEALTH + * mode to tell what options to process: + * [LS]SRR (pass 0) or the others (pass 1). + * The reason for as many as two passes is that when doing IPSTEALTH, + * non-routing options should be processed only if the packet is for us. * Returns 1 if packet has been forwarded/freed, * 0 if the packet should be processed further. */ static int -ip_dooptions(m) +ip_dooptions(m, pass) struct mbuf *m; + int pass; { register struct ip *ip = mtod(m, struct ip *); register u_char *cp; @@ -1201,6 +1220,10 @@ ip_dooptions(m) */ case IPOPT_LSRR: case IPOPT_SSRR: +#ifdef IPSTEALTH + if (ipstealth && pass > 0) + break; +#endif if (optlen < IPOPT_OFFSET + sizeof(*cp)) { code = &cp[IPOPT_OLEN] - (u_char *)ip; goto bad; @@ -1236,7 +1259,10 @@ ip_dooptions(m) save_rte(cp, ip->ip_src); break; } - +#ifdef IPSTEALTH + if (ipstealth) + goto dropit; +#endif if (!ip_dosourceroute) { if (ipforwarding) { char buf[16]; /* aaa.bbb.ccc.ddd\0 */ @@ -1255,6 +1281,9 @@ nosourcerouting: /* * Not acting as a router, so silently drop. */ +#ifdef IPSTEALTH +dropit: +#endif ipstat.ips_cantforward++; m_freem(m); return (1); @@ -1290,6 +1319,10 @@ nosourcerouting: break; case IPOPT_RR: +#ifdef IPSTEALTH + if (ipstealth && pass == 0) + break; +#endif if (optlen < IPOPT_OFFSET + sizeof(*cp)) { code = &cp[IPOPT_OFFSET] - (u_char *)ip; goto bad; @@ -1323,6 +1356,10 @@ nosourcerouting: break; case IPOPT_TS: +#ifdef IPSTEALTH + if (ipstealth && pass == 0) + break; +#endif code = cp - (u_char *)ip; if (optlen < 4 || optlen > 40) { code = &cp[IPOPT_OLEN] - (u_char *)ip; |