Implement user-setable promiscuous mode (a new `promisc' flag for ifconfig(8)).

Also, for all interfaces in this mode pass all ethernet frames to upper layer,
even those not addressed to our own MAC, which allows packets encapsulated
in those frames be processed with packet filters (ipfw(8) et al).

Emphatically requested by:	Anton Turygin <pa3op@ukr-link.net>
Valuable suggestions by:	fenner
This commit is contained in:
sobomax 2002-08-19 15:16:38 +00:00
parent be3fb71639
commit e50e3b03ec
5 changed files with 22 additions and 4 deletions

View File

@ -237,6 +237,10 @@ Enable driver dependent debugging code; usually, this turns on
extra console error logging.
.It Fl debug
Disable driver dependent debugging code.
.It Cm promisc
Put interface into permanently promiscuous mode.
.It Fl promisc
Disable permanently promiscuous mode.
.It Cm delete
Another name for the
.Fl alias

View File

@ -202,6 +202,8 @@ struct cmd {
{ "-arp", IFF_NOARP, setifflags },
{ "debug", IFF_DEBUG, setifflags },
{ "-debug", -IFF_DEBUG, setifflags },
{ "promisc", IFF_PPROMISC, setifflags },
{ "-promisc", -IFF_PPROMISC, setifflags },
{ "add", IFF_UP, notealias },
{ "alias", IFF_UP, notealias },
{ "-alias", -IFF_UP, notealias },
@ -999,7 +1001,7 @@ setifflags(const char *vname, int value, int s, const struct afswtch *afp)
exit(1);
}
strncpy(my_ifr.ifr_name, name, sizeof (my_ifr.ifr_name));
flags = (my_ifr.ifr_flags & 0xffff) | (my_ifr.ifr_flagshigh << 16);
flags = (my_ifr.ifr_flags & 0xffff) | (my_ifr.ifr_flagshigh << 16);
if (value < 0) {
value = -value;

View File

@ -1291,6 +1291,12 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
}
ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
(new_flags &~ IFF_CANTCHANGE);
if (new_flags & IFF_PPROMISC) {
/* Permanently promiscuous mode requested */
ifp->if_flags |= IFF_PROMISC;
} else if (ifp->if_pcount == 0) {
ifp->if_flags &= ~IFF_PROMISC;
}
if (ifp->if_ioctl)
(void) (*ifp->if_ioctl)(ifp, cmd, data);
getmicrotime(&ifp->if_lastchange);
@ -1561,6 +1567,11 @@ ifpromisc(ifp, pswitch)
oldpcount = ifp->if_pcount;
oldflags = ifp->if_flags;
if (ifp->if_flags & IFF_PPROMISC) {
/* Do nothing if device is in permanently promiscuous mode */
ifp->if_pcount += pswitch ? 1 : -1;
return (0);
}
if (pswitch) {
/*
* If the device is not configured up, we cannot put it in

View File

@ -140,11 +140,12 @@ struct if_data {
#define IFF_ALTPHYS IFF_LINK2 /* use alternate physical connection */
#define IFF_MULTICAST 0x8000 /* supports multicast */
#define IFF_POLLING 0x10000 /* Interface is in polling mode. */
#define IFF_PPROMISC 0x20000 /* user-requested promisc mode */
/* flags set internally only: */
#define IFF_CANTCHANGE \
(IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_SMART)
IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_SMART|IFF_PROMISC)
/* Capabilities that interfaces can advertise. */
#define IFCAP_RXCSUM 0x0001 /* can offload checksum on RX */

View File

@ -677,7 +677,8 @@ ether_demux(ifp, eh, m)
if ((ifp->if_flags & IFF_PROMISC) != 0
&& (eh->ether_dhost[0] & 1) == 0
&& bcmp(eh->ether_dhost,
IFP2AC(ifp)->ac_enaddr, ETHER_ADDR_LEN) != 0) {
IFP2AC(ifp)->ac_enaddr, ETHER_ADDR_LEN) != 0
&& (ifp->if_flags && IFF_PPROMISC) == 0) {
m_freem(m);
return;
}
@ -1076,4 +1077,3 @@ ether_resolvemulti(ifp, llsa, sa)
return EAFNOSUPPORT;
}
}