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 [EMAIL PROTECTED]
with "unsubscribe freebsd-net" in the body of the message

Reply via email to