Properly program the multicast filter in ndis_setmulti(),
and fix promisc mode in ndis_ioctl().
This commit is contained in:
parent
575f4d3239
commit
f98f50fcfd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=124709
@ -172,10 +172,71 @@ static void
|
|||||||
ndis_setmulti(sc)
|
ndis_setmulti(sc)
|
||||||
struct ndis_softc *sc;
|
struct ndis_softc *sc;
|
||||||
{
|
{
|
||||||
#ifdef notyet
|
struct ifnet *ifp;
|
||||||
uint32_t ndis_filter;
|
struct ifmultiaddr *ifma;
|
||||||
int len;
|
int len, mclistsz, error;
|
||||||
#endif
|
uint8_t *mclist;
|
||||||
|
|
||||||
|
ifp = &sc->arpcom.ac_if;
|
||||||
|
|
||||||
|
if (!(ifp->if_flags & IFF_UP))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
|
||||||
|
sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
|
||||||
|
len = sizeof(sc->ndis_filter);
|
||||||
|
error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
|
||||||
|
&sc->ndis_filter, &len);
|
||||||
|
if (error)
|
||||||
|
device_printf (sc->ndis_dev,
|
||||||
|
"set filter failed: %d\n", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
len = sizeof(mclistsz);
|
||||||
|
ndis_get_info(sc, OID_802_3_MAXIMUM_LIST_SIZE, &mclistsz, &len);
|
||||||
|
|
||||||
|
mclist = malloc(ETHER_ADDR_LEN * mclistsz, M_TEMP, M_NOWAIT);
|
||||||
|
|
||||||
|
if (mclist == NULL) {
|
||||||
|
sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
sc->ndis_filter |= NDIS_PACKET_TYPE_MULTICAST;
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
|
||||||
|
if (ifma->ifma_addr->sa_family != AF_LINK)
|
||||||
|
continue;
|
||||||
|
bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
|
||||||
|
mclist + (ETHER_ADDR_LEN * len), ETHER_ADDR_LEN);
|
||||||
|
len++;
|
||||||
|
if (len > mclistsz) {
|
||||||
|
sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
|
||||||
|
sc->ndis_filter &= ~NDIS_PACKET_TYPE_MULTICAST;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len = len * ETHER_ADDR_LEN;
|
||||||
|
error = ndis_set_info(sc, OID_802_3_MULTICAST_LIST, mclist, &len);
|
||||||
|
if (error) {
|
||||||
|
device_printf (sc->ndis_dev, "set mclist failed: %d\n", error);
|
||||||
|
sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
|
||||||
|
sc->ndis_filter &= ~NDIS_PACKET_TYPE_MULTICAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(mclist, M_TEMP);
|
||||||
|
|
||||||
|
len = sizeof(sc->ndis_filter);
|
||||||
|
error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
|
||||||
|
&sc->ndis_filter, &len);
|
||||||
|
if (error)
|
||||||
|
device_printf (sc->ndis_dev, "set filter failed: %d\n", error);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1149,9 +1210,6 @@ ndis_init(xsc)
|
|||||||
struct ndis_softc *sc = xsc;
|
struct ndis_softc *sc = xsc;
|
||||||
struct ifnet *ifp = &sc->arpcom.ac_if;
|
struct ifnet *ifp = &sc->arpcom.ac_if;
|
||||||
int i, error;
|
int i, error;
|
||||||
uint32_t ndis_filter = 0;
|
|
||||||
|
|
||||||
/*NDIS_LOCK(sc);*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cancel pending I/O and free all RX/TX buffers.
|
* Cancel pending I/O and free all RX/TX buffers.
|
||||||
@ -1161,48 +1219,46 @@ ndis_init(xsc)
|
|||||||
ndis_init_nic(sc);
|
ndis_init_nic(sc);
|
||||||
|
|
||||||
/* Init our MAC address */
|
/* Init our MAC address */
|
||||||
#ifdef notdef
|
|
||||||
/*
|
|
||||||
* Program the multicast filter, if necessary.
|
|
||||||
*/
|
|
||||||
ndis_setmulti(sc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Program the packet filter */
|
/* Program the packet filter */
|
||||||
|
|
||||||
ndis_filter = NDIS_PACKET_TYPE_DIRECTED;
|
sc->ndis_filter = NDIS_PACKET_TYPE_DIRECTED;
|
||||||
|
|
||||||
if (ifp->if_flags & IFF_BROADCAST)
|
if (ifp->if_flags & IFF_BROADCAST)
|
||||||
ndis_filter |= NDIS_PACKET_TYPE_BROADCAST;
|
sc->ndis_filter |= NDIS_PACKET_TYPE_BROADCAST;
|
||||||
|
|
||||||
if (ifp->if_flags & IFF_PROMISC)
|
if (ifp->if_flags & IFF_PROMISC)
|
||||||
ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS;
|
sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS;
|
||||||
|
|
||||||
if (ifp->if_flags & IFF_MULTICAST)
|
i = sizeof(sc->ndis_filter);
|
||||||
ndis_filter |= NDIS_PACKET_TYPE_MULTICAST;
|
|
||||||
|
|
||||||
i = sizeof(ndis_filter);
|
|
||||||
|
|
||||||
error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
|
error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER,
|
||||||
&ndis_filter, &i);
|
&sc->ndis_filter, &i);
|
||||||
|
|
||||||
sc->ndis_filter = ndis_filter;
|
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
device_printf (sc->ndis_dev, "set filter failed: %d\n", error);
|
device_printf (sc->ndis_dev, "set filter failed: %d\n", error);
|
||||||
|
|
||||||
sc->ndis_txidx = 0;
|
/*
|
||||||
sc->ndis_txpending = sc->ndis_maxpkts;
|
* Program the multicast filter, if necessary.
|
||||||
sc->ndis_link = 0;
|
*/
|
||||||
|
ndis_setmulti(sc);
|
||||||
|
|
||||||
ndis_enable_intr(sc);
|
ndis_enable_intr(sc);
|
||||||
|
|
||||||
if (sc->ndis_80211)
|
if (sc->ndis_80211)
|
||||||
ndis_setstate_80211(sc);
|
ndis_setstate_80211(sc);
|
||||||
|
|
||||||
|
NDIS_LOCK(sc);
|
||||||
|
|
||||||
|
sc->ndis_txidx = 0;
|
||||||
|
sc->ndis_txpending = sc->ndis_maxpkts;
|
||||||
|
sc->ndis_link = 0;
|
||||||
|
|
||||||
ifp->if_flags |= IFF_RUNNING;
|
ifp->if_flags |= IFF_RUNNING;
|
||||||
ifp->if_flags &= ~IFF_OACTIVE;
|
ifp->if_flags &= ~IFF_OACTIVE;
|
||||||
|
|
||||||
|
NDIS_UNLOCK(sc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some drivers don't set this value. The NDIS spec says
|
* Some drivers don't set this value. The NDIS spec says
|
||||||
* the default checkforhang timeout is approximately 2
|
* the default checkforhang timeout is approximately 2
|
||||||
@ -1215,8 +1271,6 @@ ndis_init(xsc)
|
|||||||
sc->ndis_stat_ch = timeout(ndis_tick, sc,
|
sc->ndis_stat_ch = timeout(ndis_tick, sc,
|
||||||
hz * sc->ndis_block.nmb_checkforhangsecs);
|
hz * sc->ndis_block.nmb_checkforhangsecs);
|
||||||
|
|
||||||
/*NDIS_UNLOCK(sc);*/
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1665,7 +1719,6 @@ ndis_ioctl(ifp, command, data)
|
|||||||
|
|
||||||
/*NDIS_LOCK(sc);*/
|
/*NDIS_LOCK(sc);*/
|
||||||
|
|
||||||
|
|
||||||
switch(command) {
|
switch(command) {
|
||||||
case SIOCSIFFLAGS:
|
case SIOCSIFFLAGS:
|
||||||
if (ifp->if_flags & IFF_UP) {
|
if (ifp->if_flags & IFF_UP) {
|
||||||
@ -1674,7 +1727,8 @@ ndis_ioctl(ifp, command, data)
|
|||||||
!(sc->ndis_if_flags & IFF_PROMISC)) {
|
!(sc->ndis_if_flags & IFF_PROMISC)) {
|
||||||
sc->ndis_filter |=
|
sc->ndis_filter |=
|
||||||
NDIS_PACKET_TYPE_PROMISCUOUS;
|
NDIS_PACKET_TYPE_PROMISCUOUS;
|
||||||
ndis_set_info(sc,
|
i = sizeof(sc->ndis_filter);
|
||||||
|
error = ndis_set_info(sc,
|
||||||
OID_GEN_CURRENT_PACKET_FILTER,
|
OID_GEN_CURRENT_PACKET_FILTER,
|
||||||
&sc->ndis_filter, &i);
|
&sc->ndis_filter, &i);
|
||||||
} else if (ifp->if_flags & IFF_RUNNING &&
|
} else if (ifp->if_flags & IFF_RUNNING &&
|
||||||
@ -1682,7 +1736,8 @@ ndis_ioctl(ifp, command, data)
|
|||||||
sc->ndis_if_flags & IFF_PROMISC) {
|
sc->ndis_if_flags & IFF_PROMISC) {
|
||||||
sc->ndis_filter &=
|
sc->ndis_filter &=
|
||||||
~NDIS_PACKET_TYPE_PROMISCUOUS;
|
~NDIS_PACKET_TYPE_PROMISCUOUS;
|
||||||
ndis_set_info(sc,
|
i = sizeof(sc->ndis_filter);
|
||||||
|
error = ndis_set_info(sc,
|
||||||
OID_GEN_CURRENT_PACKET_FILTER,
|
OID_GEN_CURRENT_PACKET_FILTER,
|
||||||
&sc->ndis_filter, &i);
|
&sc->ndis_filter, &i);
|
||||||
} else
|
} else
|
||||||
|
Loading…
Reference in New Issue
Block a user