diff options
author | Julian Elischer <julian@FreeBSD.org> | 1998-06-12 01:54:29 +0000 |
---|---|---|
committer | Julian Elischer <julian@FreeBSD.org> | 1998-06-12 01:54:29 +0000 |
commit | bab04eb8165bc6b49ecc38ce9751d5afdc4fd184 (patch) | |
tree | c5ef887f119c9b703d474ee5d3b50cd235dcfbe5 | |
parent | 0774c3c25a7525fe88f0f9f2fc512c421bf2f56b (diff) | |
download | src-bab04eb8165bc6b49ecc38ce9751d5afdc4fd184.tar.gz src-bab04eb8165bc6b49ecc38ce9751d5afdc4fd184.zip |
Allow diverted packets from the transmit side to remember if they
had a recv interface and allow that state to be available
after re-injection for further tests.
Notes
Notes:
svn path=/head/; revision=36903
-rw-r--r-- | sys/netinet/ip_divert.c | 53 |
1 files changed, 26 insertions, 27 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index f6b850b30dfb..64aa114f8eab 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ip_divert.c,v 1.28 1998/06/06 19:39:08 julian Exp $ + * $Id: ip_divert.c,v 1.29 1998/06/06 20:45:25 julian Exp $ */ #include "opt_inet.h" @@ -178,7 +178,6 @@ div_input(struct mbuf *m, int hlen) divsrc.sin_addr.s_addr = 0; if (hlen) { struct ifaddr *ifa; - char name[32]; #ifdef DIAGNOSTIC /* Sanity check */ @@ -200,6 +199,9 @@ div_input(struct mbuf *m, int hlen) ((struct sockaddr_in *) ifa->ifa_addr)->sin_addr; break; } + } + if (m->m_pkthdr.rcvif) { + char name[32]; /* * Hide the actual interface name in there in the * sin_zero array. XXX This needs to be moved to a @@ -267,21 +269,38 @@ div_output(so, m, addr, control) if (control) m_freem(control); /* XXX */ - /* Loopback avoidance */ + /* Loopback avoidance and state recovery */ if (sin) { + int len = 0; + char *c = sin->sin_zero; #ifdef IPFW_DIVERT_OLDRESTART ip_divert_cookie = ntohs(sin->sin_port); #else ip_divert_cookie = sin->sin_port; #endif /* IPFW_DIVERT_OLDRESTART */ + + /* + * Find receive interface with the given name or IP address. + * The name is user supplied data so don't trust it's size or + * that it is zero terminated. The name has priority. + * We are presently assuming that the sockaddr_in + * has not been replaced by a sockaddr_div, so we limit it + * to 16 bytes in total. the name is stuffed (if it exists) + * in the sin_zero[] field. + */ + while (*c++ && (len++ < sizeof(sin->sin_zero))); + if ((len > 0) && (len < sizeof(sin->sin_zero))) + m->m_pkthdr.rcvif = ifunit(sin->sin_zero); } else { ip_divert_cookie = 0; } /* Reinject packet into the system as incoming or outgoing */ if (!sin || sin->sin_addr.s_addr == 0) { - /* Don't allow both user specified and setsockopt options, - and don't allow packet length sizes that will crash */ + /* + * Don't allow both user specified and setsockopt options, + * and don't allow packet length sizes that will crash + */ if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options) || ((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) { error = EINVAL; @@ -298,30 +317,10 @@ div_output(so, m, addr, control) (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST | IP_RAWOUTPUT, inp->inp_moptions); } else { - struct ifnet *ifp = NULL; struct ifaddr *ifa; - int len = 0; - char *c = sin->sin_zero; - - sin->sin_port = 0; - - /* - * Find receive interface with the given name or IP address. - * The name is user supplied data so don't trust it's size or - * that it is zero terminated. The name has priority. - * We are presently assuming that the sockaddr_in - * has not been replaced by a sockaddr_div, so we limit it - * to 16 bytes in total. the name is stuffed (if it exists) - * in the sin_zero[] field. - */ - while (*c++ && (len++ < sizeof(sin->sin_zero))); - if ((len > 0) && (len < sizeof(sin->sin_zero))) - ifp = ifunit(sin->sin_zero); - /* If no luck with the name. check by IP address. */ - if (ifp) { - m->m_pkthdr.rcvif = ifp; - } else { + /* If no luck with the name above. check by IP address. */ + if (m->m_pkthdr.rcvif == NULL) { if (!(ifa = ifa_ifwithaddr((struct sockaddr *) sin))) { error = EADDRNOTAVAIL; goto cantsend; |