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.
This commit is contained in:
julian 1998-06-12 01:54:29 +00:00
parent 8f454b5401
commit 7fe2cc176d

View File

@ -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;