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:
parent
359526bbe8
commit
80b9cdec4f
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user