Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Dec 2001 18:51:18 +0300
From:      Yar Tikhiy <yar@FreeBSD.org>
To:        Maxim Konovalov <maxim@macomnet.ru>
Cc:        net@FreeBSD.org, hackers@FreeBSD.org
Subject:   Re: Processing IP options reveals IPSTEALH router
Message-ID:  <20011221185118.B25868@comp.chem.msu.su>
In-Reply-To: <20011219195659.G25693-100000@news1.macomnet.ru>; from maxim@macomnet.ru on Wed, Dec 19, 2001 at 08:54:50PM %2B0300
References:  <20011219194903.D21732@comp.chem.msu.su> <20011219195659.G25693-100000@news1.macomnet.ru>

next in thread | previous in thread | raw e-mail | index | archive | help
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-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011221185118.B25868>