From owner-freebsd-net Sat Dec 22 11:15:15 2001 Delivered-To: freebsd-net@freebsd.org Received: from comp.chem.msu.su (comp-ext.chem.msu.su [158.250.32.157]) by hub.freebsd.org (Postfix) with ESMTP id 5529F37B41E; Sat, 22 Dec 2001 11:14:22 -0800 (PST) Received: (from yar@localhost) by comp.chem.msu.su (8.11.1/8.11.1) id fBLFpJR28804; Fri, 21 Dec 2001 18:51:19 +0300 (MSK) (envelope-from yar) Date: Fri, 21 Dec 2001 18:51:18 +0300 From: Yar Tikhiy To: Maxim Konovalov Cc: net@FreeBSD.org, hackers@FreeBSD.org Subject: Re: Processing IP options reveals IPSTEALH router Message-ID: <20011221185118.B25868@comp.chem.msu.su> References: <20011219194903.D21732@comp.chem.msu.su> <20011219195659.G25693-100000@news1.macomnet.ru> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20011219195659.G25693-100000@news1.macomnet.ru>; from maxim@macomnet.ru on Wed, Dec 19, 2001 at 08:54:50PM +0300 Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org On Wed, Dec 19, 2001 at 08:54:50PM +0300, Maxim Konovalov wrote: > On 19:49+0300, Dec 19, 2001, Yar Tikhiy wrote: > > > As for source routing, I believe a stealthy router should just drop > > such packets as though it were a host. Of course, source-routed > > packets destined for the router itself should be accepted. > > So there are three IPSTEALTH cases: > > 1/ the dst address is not ours, net.inet.ip.sourceroute=0, > net.inet.ip.forwarding=1: process ip options by ip_dooptions(). > > 2/ the dst address is ours: process ip options by ip_dooptions(), > > 3/ in other cases do not process ip options. I made a patch that adds the "stealthy IP options feature". Honestly, now I'm afraid it's "much ado about nothing", given how clumsy solution is needed for such a small problem. Even the way of ignoring IP options completely when doing IPSTEALTH looks way better... -- Yar P.S. Here's the patch: --- ip_input.c.orig Fri Dec 7 00:54:48 2001 +++ ip_input.c Fri Dec 21 17:59:22 2001 @@ -211,7 +211,7 @@ 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 @@ -499,7 +499,7 @@ * 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 @@ -657,6 +657,19 @@ 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++; @@ -1150,12 +1163,18 @@ * 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 non-routing options + * must not be processed if the packet isn't for us when doing IPSTEALH. * 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; @@ -1200,6 +1219,10 @@ */ 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; @@ -1235,7 +1258,10 @@ 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 */ @@ -1254,6 +1280,9 @@ /* * Not acting as a router, so silently drop. */ +#ifdef IPSTEALTH +dropit: +#endif ipstat.ips_cantforward++; m_freem(m); return (1); @@ -1289,6 +1318,10 @@ 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; @@ -1322,6 +1355,10 @@ 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; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message