--- 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 , then fdp is outgoing interface, fr != NULL + * 3) dupto , then fdp is outgoing interface, fr != NULL + * 4) fastroute, then fdp = NULL + */ + /* * In case we're here due to "to " 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 :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. */