summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/ifconfig/ifconfig.84
-rw-r--r--sbin/ifconfig/ifconfig.c4
-rw-r--r--sys/net/if.c11
-rw-r--r--sys/net/if.h3
-rw-r--r--sys/net/if_ethersubr.c4
5 files changed, 22 insertions, 4 deletions
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index be8fd50..39761fb 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -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
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index 67c293e..c9ab382 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -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;
diff --git a/sys/net/if.c b/sys/net/if.c
index 969963d..a551148 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -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
diff --git a/sys/net/if.h b/sys/net/if.h
index fc95786..8453ff5 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -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 */
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 53c744d..af1421d 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -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;
}
}
-
OpenPOWER on IntegriCloud