Index: sys/net80211/ieee80211_freebsd.h =================================================================== --- sys/net80211/ieee80211_freebsd.h +++ sys/net80211/ieee80211_freebsd.h @@ -39,6 +39,10 @@ #include #include +#ifdef NETDUMP +#include +#endif + /* * Common state locking definitions. */ @@ -487,6 +491,36 @@ struct ieee80211req *); SET_DECLARE(ieee80211_ioctl_setset, ieee80211_ioctl_setfunc); #define IEEE80211_IOCTL_SET(_name, _set) TEXT_SET(ieee80211_ioctl_setset, _set) + +#ifdef NETDUMP +typedef void net80211dump_init_t(struct ieee80211com *, int *nrxr, int *ncl, + int *clsize); +typedef void net80211dump_event_t(struct ieee80211com *, enum netdump_ev); +typedef int net80211dump_poll_t(struct ieee80211com *, int); + +struct net80211dump_methods { + net80211dump_init_t *nd8_init; + net80211dump_event_t *nd8_event; + net80211dump_poll_t *nd8_poll; +}; + +#define NET80211DUMP_DEFINE(driver) \ + static net80211dump_init_t driver##_net80211dump_init; \ + static net80211dump_event_t driver##_net80211dump_event; \ + static net80211dump_poll_t driver##_net80211dump_poll; \ + \ + static struct net80211dump_methods driver##_net80211dump_methods = { \ + .nd8_init = driver##_net80211dump_init, \ + .nd8_event = driver##_net80211dump_event, \ + .nd8_poll = driver##_net80211dump_poll, \ + } +#define NET80211DUMP_SET(ic, driver) \ + (ic)->ic_netdump_meth = &driver##_net80211dump_methods +#else +#define NET80211DUMP_DEFINE(driver) +#define NET80211DUMP_SET(ic, driver) +#endif /* NETDUMP */ + #endif /* _KERNEL */ /* XXX this stuff belongs elsewhere */ Index: sys/net80211/ieee80211_freebsd.c =================================================================== --- sys/net80211/ieee80211_freebsd.c +++ sys/net80211/ieee80211_freebsd.c @@ -69,6 +69,7 @@ #endif static MALLOC_DEFINE(M_80211_COM, "80211com", "802.11 com state"); +NETDUMP_DEFINE(ieee80211); static const char wlanname[] = "wlan"; static struct if_clone *wlan_cloner; @@ -112,7 +113,14 @@ cp.icp_flags & IEEE80211_CLONE_MACADDR ? cp.icp_macaddr : ic->ic_macaddr); - return (vap == NULL ? EIO : 0); + if (vap == NULL) + return (EIO); + +#ifdef NETDUMP + if (ic->ic_netdump_meth != NULL) + NETDUMP_SET(vap->iv_ifp, ieee80211); +#endif + return (0); } static void @@ -973,6 +981,54 @@ } } +#ifdef NETDUMP +static void +ieee80211_netdump_init(struct ifnet *ifp, int *nrxr, int *ncl, int *clsize) +{ + struct ieee80211vap *vap; + struct ieee80211com *ic; + + vap = if_getsoftc(ifp); + ic = vap->iv_ic; + + IEEE80211_LOCK(ic); + ic->ic_netdump_meth->nd8_init(ic, nrxr, ncl, clsize); + IEEE80211_UNLOCK(ic); +} + +static void +ieee80211_netdump_event(struct ifnet *ifp, enum netdump_ev ev) +{ + struct ieee80211vap *vap; + struct ieee80211com *ic; + + vap = if_getsoftc(ifp); + ic = vap->iv_ic; + + IEEE80211_LOCK(ic); + ic->ic_netdump_meth->nd8_event(ic, ev); + IEEE80211_UNLOCK(ic); +} + +static int +ieee80211_netdump_transmit(struct ifnet *ifp, struct mbuf *m) +{ + return (ieee80211_vap_transmit(ifp, m)); +} + +static int +ieee80211_netdump_poll(struct ifnet *ifp, int count) +{ + struct ieee80211vap *vap; + struct ieee80211com *ic; + + vap = if_getsoftc(ifp); + ic = vap->iv_ic; + + return (ic->ic_netdump_meth->nd8_poll(ic, count)); +} +#endif + /* * Module glue. * Index: sys/net80211/ieee80211_var.h =================================================================== --- sys/net80211/ieee80211_var.h +++ sys/net80211/ieee80211_var.h @@ -370,6 +370,9 @@ /* The channel width has changed (20<->2040) */ void (*ic_update_chw)(struct ieee80211com *); +#ifdef NETDUMP + const struct net80211dump_methods *ic_netdump_meth; +#endif uint64_t ic_spare[7]; };