On Wed, Dec 04, 2002 at 11:37:17PM -0500, Ilya wrote:
> default router is Cable. IPNAT works fine, no problem. but any incoming
> traffic to services on DSL interface is being replied to from cable
> interface. Therefore rendering DSL useless.
> Have anyone been able to solve this problem? Or has any suggestions to it?

Yes you can solve it with a patch and a rule like this:

pass in on <dsl-if> to <dls-if>:<router> <your spec> keep state

e.g.:
pass in on ep0 to ep0:1.2.3.4 from any to 10.0.0.1 port 80 keep state

Normally ipfilter does not remember the interface a packet came in from,
and the abover rule is disallowed.

I made the attached patch a long time ago and probably it is not 100% correct.
But it works for me.  Use at your own risk and be advised I have
absolutelyu no time right now to support it.

-Guido
--- ip_fil.c.orig       Sat Aug 31 18:24:52 2002
+++ ip_fil.c    Thu Dec  5 08:45:27 2002
@@ -1605,16 +1605,67 @@
                ifp = fin->fin_ifp;
 
        /*
+        * There are multiple ways to get here
+        * 1) via send_ip as a response to an incoming packet, the fdp == NULL
+        * 2) to <if>, then fdp is outgoing interface, fr != NULL
+        * 3) dupto <if>, then fdp is outgoing interface, fr != NULL
+        * 4) fastroute, then fdp = NULL
+        */
+       /*
         * In case we're here due to "to <if>" being used with "keep state",
         * check that we're going in the correct direction.
         */
-       if ((fr != NULL) && (fin->fin_rev != 0)) {
-               if ((ifp != NULL) && (fdp == &fr->fr_tif))
-                       return 0;
+       if ((fr != NULL) && (fdp != NULL) &&
+           ((ip->ip_dst.s_addr & fr->fr_smsk.s_addr) == fr->fr_src.s_addr) &&
+           ((ip->ip_src.s_addr & fr->fr_dmsk.s_addr) == fr->fr_dst.s_addr)) {
+               /* We get here when we match a filterrule reversed (i.e.
+               * a return packet
+               */
+               /* kludge to get on "on ed0 to ed0:1.2.3.4" working */
+               if (fr->fr_ifa == fdp->fd_ifp) {
+                       /* if outgoing interface equals rule interface */
+                       ifp = fdp->fd_ifp;
+                       /* send it to ip address in to: rule if available */
+                       if (fdp->fd_ip.s_addr != 0) {
+                               dst->sin_addr = fdp->fd_ip;
+                       }
+               } else {
+                       /* if outgoing interface doesn't match rule interface */
+                       ifp = fr->fr_ifa;
+               }
+       } else if ((fr != NULL) && (fdp != NULL)) {
+               /* kludge to get on "on ed0 to ed0:1.2.3.4" working */
+               if (fr->fr_ifa == fdp->fd_ifp) {
+                       ifp = NULL;
+               } else {
+                       ifp = fdp->fd_ifp;
+                       if (fdp->fd_ip.s_addr != 0) {
+                               dst->sin_addr = fdp->fd_ip;
+                       }
+               }
        } else if (fdp != NULL) {
-               if (fdp->fd_ip.s_addr != 0)
+               if (fdp->fd_ip.s_addr != 0) {
                        dst->sin_addr = fdp->fd_ip;
+               }
+       } else {
+               /* fdp equals NULL */
+               /* We came here via return something */
+               if ((fr != NULL) && fr->fr_tif.fd_ifp &&
+               (fr->fr_tif.fd_ifp != (void *)-1) &&
+               fr->fr_tif.fd_ip.s_addr) {
+                       /* This means we have a rule like:
+                       * block return-rst to <if>:ip address
+                       */
+                       dst->sin_addr = fr->fr_tif.fd_ip;
+               }
        }
+       /*
+       * An incoming packet from the interface we are sending packets to.
+       * We don't really want to route it.
+       */
+       if ((fin->fin_out == 0) && (fdp == &fr->fr_tif) &&
+       (ifp == fin->fin_ifp))
+               return 0;
 
 # if BSD >= 199306
        dst->sin_len = sizeof(*dst);
@@ -1634,12 +1685,14 @@
        ROUTE_UNLOCK();
 #endif
 
+#if 0
        if (!ifp) {
                if (!fr || !(fr->fr_flags & FR_FASTROUTE)) {
                        error = -2;
                        goto bad;
                }
        }
+#endif
 
        if ((ifp == NULL) && (ro->ro_rt != NULL))
                ifp = ro->ro_rt->rt_ifp;
@@ -1681,6 +1734,9 @@
                fin->fin_ifp = sifp;
        } else
                ip->ip_sum = 0;
+/*XXX*/
+       ip->ip_sum = 0;
+
        /*
         * If small enough for interface, can just send directly.
         */

Reply via email to