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-net" 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>
