aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/ip_divert.c
diff options
context:
space:
mode:
authorJulian Elischer <julian@FreeBSD.org>1998-06-12 01:54:29 +0000
committerJulian Elischer <julian@FreeBSD.org>1998-06-12 01:54:29 +0000
commitbab04eb8165bc6b49ecc38ce9751d5afdc4fd184 (patch)
treec5ef887f119c9b703d474ee5d3b50cd235dcfbe5 /sys/netinet/ip_divert.c
parent0774c3c25a7525fe88f0f9f2fc512c421bf2f56b (diff)
downloadsrc-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
Diffstat (limited to 'sys/netinet/ip_divert.c')
-rw-r--r--sys/netinet/ip_divert.c53
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;