Add support for monitor mode. This means that after enabling the
correct mode via ancontrol, you can use bpf to sniff raw 802.11 frames. Who want's to port AirSnort. ;-) Submitted by: Doug Ambrisko <ambrisko@ambrisko.com> (author) David Wolfskill <david@catwhisker.org> (port to current)
This commit is contained in:
parent
8cdfefbd0c
commit
51331cf32a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=83269
@ -102,6 +102,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/module.h>
|
#include <sys/module.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
#include <machine/bus.h>
|
#include <machine/bus.h>
|
||||||
#include <sys/rman.h>
|
#include <sys/rman.h>
|
||||||
@ -169,6 +170,68 @@ static int an_media_change __P((struct ifnet *));
|
|||||||
static void an_media_status __P((struct ifnet *, struct ifmediareq *));
|
static void an_media_status __P((struct ifnet *, struct ifmediareq *));
|
||||||
|
|
||||||
static int an_dump = 0;
|
static int an_dump = 0;
|
||||||
|
static char an_conf[256];
|
||||||
|
|
||||||
|
/* sysctl vars */
|
||||||
|
SYSCTL_NODE(_machdep, OID_AUTO, an, CTLFLAG_RD, 0, "dump RID");
|
||||||
|
|
||||||
|
static int
|
||||||
|
sysctl_an_dump(SYSCTL_HANDLER_ARGS)
|
||||||
|
{
|
||||||
|
int error, r, last;
|
||||||
|
char *s = an_conf;
|
||||||
|
|
||||||
|
last = an_dump;
|
||||||
|
bzero(an_conf, sizeof(an_conf));
|
||||||
|
|
||||||
|
switch (an_dump){
|
||||||
|
case 0:
|
||||||
|
strcat(an_conf, "off");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
strcat(an_conf, "type");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
strcat(an_conf, "dump");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(an_conf, 5, "%x", an_dump);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = sysctl_handle_string(oidp, an_conf, sizeof(an_conf), req);
|
||||||
|
|
||||||
|
if (strncmp(an_conf,"off", 4) == 0){
|
||||||
|
an_dump = 0;
|
||||||
|
}
|
||||||
|
if (strncmp(an_conf,"dump", 4) == 0){
|
||||||
|
an_dump = 1;
|
||||||
|
}
|
||||||
|
if (strncmp(an_conf,"type", 4) == 0){
|
||||||
|
an_dump = 2;
|
||||||
|
}
|
||||||
|
if (*s == 'f'){
|
||||||
|
r = 0;
|
||||||
|
for(;;s++){
|
||||||
|
if((*s >= '0') && (*s <= '9')){
|
||||||
|
r = r * 16 + (*s - '0');
|
||||||
|
}else if ((*s >= 'a') && (*s <= 'f')) {
|
||||||
|
r = r * 16 + (*s - 'a' + 10);
|
||||||
|
}else{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
an_dump = r;
|
||||||
|
}
|
||||||
|
if (an_dump != last)
|
||||||
|
printf("Sysctl changed for Aironet driver\n");
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYSCTL_PROC(_machdep, OID_AUTO, an_dump, CTLTYPE_STRING | CTLFLAG_RW,
|
||||||
|
0, sizeof(an_conf), sysctl_an_dump, "A", "");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We probe for an Aironet 4500/4800 card by attempting to
|
* We probe for an Aironet 4500/4800 card by attempting to
|
||||||
* read the default SSID list. On reset, the first entry in
|
* read the default SSID list. On reset, the first entry in
|
||||||
@ -303,6 +366,8 @@ int an_attach(sc, unit, flags)
|
|||||||
|
|
||||||
sc->an_gone = 0;
|
sc->an_gone = 0;
|
||||||
sc->an_associated = 0;
|
sc->an_associated = 0;
|
||||||
|
sc->an_monitor = 0;
|
||||||
|
sc->an_was_monitor = 0;
|
||||||
|
|
||||||
/* Reset the NIC. */
|
/* Reset the NIC. */
|
||||||
an_reset(sc);
|
an_reset(sc);
|
||||||
@ -424,90 +489,160 @@ int an_attach(sc, unit, flags)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void an_rxeof(sc)
|
static void
|
||||||
struct an_softc *sc;
|
an_rxeof(sc)
|
||||||
|
struct an_softc *sc;
|
||||||
{
|
{
|
||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
struct ether_header *eh;
|
struct ether_header *eh;
|
||||||
#ifdef ANCACHE
|
struct ieee80211_frame *ih;
|
||||||
struct an_rxframe rx_frame;
|
struct an_rxframe rx_frame;
|
||||||
#endif
|
struct an_rxframe_802_3 rx_frame_802_3;
|
||||||
struct an_rxframe_802_3 rx_frame_802_3;
|
struct mbuf *m;
|
||||||
struct mbuf *m;
|
int len, id, error = 0;
|
||||||
int id, error = 0;
|
int ieee80211_header_len;
|
||||||
|
u_char *bpf_buf;
|
||||||
|
u_short fc1;
|
||||||
|
|
||||||
ifp = &sc->arpcom.ac_if;
|
ifp = &sc->arpcom.ac_if;
|
||||||
|
|
||||||
id = CSR_READ_2(sc, AN_RX_FID);
|
id = CSR_READ_2(sc, AN_RX_FID);
|
||||||
|
|
||||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) {
|
||||||
if (m == NULL) {
|
/* read raw 802.11 packet */
|
||||||
ifp->if_ierrors++;
|
bpf_buf = sc->buf_802_11;
|
||||||
return;
|
|
||||||
}
|
|
||||||
MCLGET(m, M_DONTWAIT);
|
|
||||||
if (!(m->m_flags & M_EXT)) {
|
|
||||||
m_freem(m);
|
|
||||||
ifp->if_ierrors++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m->m_pkthdr.rcvif = ifp;
|
/* read header */
|
||||||
|
if (an_read_data(sc, id, 0x0, (caddr_t)&rx_frame,
|
||||||
|
sizeof(rx_frame))) {
|
||||||
|
ifp->if_ierrors++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
eh = mtod(m, struct ether_header *);
|
/*
|
||||||
|
* skip beacon by default since this increases the
|
||||||
|
* system load a lot
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(!(sc->an_monitor & AN_MONITOR_INCLUDE_BEACON) &&
|
||||||
|
(rx_frame.an_frame_ctl & IEEE80211_FC0_SUBTYPE_BEACON)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER){
|
||||||
|
len = rx_frame.an_rx_payload_len
|
||||||
|
+ sizeof(rx_frame);
|
||||||
|
/* Check for insane frame length */
|
||||||
|
if (len > sizeof(sc->buf_802_11)) {
|
||||||
|
printf("an%d: oversized packet received (%d, %d)\n",
|
||||||
|
sc->an_unit, len, MCLBYTES);
|
||||||
|
ifp->if_ierrors++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bcopy((char *)&rx_frame,
|
||||||
|
bpf_buf, sizeof(rx_frame));
|
||||||
|
|
||||||
|
error = an_read_data(sc, id, sizeof(rx_frame),
|
||||||
|
(caddr_t)bpf_buf+sizeof(rx_frame),
|
||||||
|
rx_frame.an_rx_payload_len);
|
||||||
|
}else{
|
||||||
|
fc1=rx_frame.an_frame_ctl >> 8;
|
||||||
|
ieee80211_header_len = sizeof(struct ieee80211_frame);
|
||||||
|
if ((fc1 & IEEE80211_FC1_DIR_TODS) &&
|
||||||
|
(fc1 & IEEE80211_FC1_DIR_FROMDS)) {
|
||||||
|
ieee80211_header_len += ETHER_ADDR_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = rx_frame.an_rx_payload_len
|
||||||
|
+ ieee80211_header_len;
|
||||||
|
/* Check for insane frame length */
|
||||||
|
if (len > sizeof(sc->buf_802_11)) {
|
||||||
|
printf("an%d: oversized packet received (%d, %d)\n",
|
||||||
|
sc->an_unit, len, MCLBYTES);
|
||||||
|
ifp->if_ierrors++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ih = (struct ieee80211_frame *)bpf_buf;
|
||||||
|
|
||||||
|
bcopy((char *)&rx_frame.an_frame_ctl,
|
||||||
|
(char *)ih, ieee80211_header_len);
|
||||||
|
|
||||||
|
error = an_read_data(sc, id, sizeof(rx_frame) +
|
||||||
|
rx_frame.an_gaplen,
|
||||||
|
(caddr_t)ih +ieee80211_header_len,
|
||||||
|
rx_frame.an_rx_payload_len);
|
||||||
|
}
|
||||||
|
/* dump raw 802.11 packet to bpf and skip ip stack */
|
||||||
|
if (ifp->if_bpf != NULL) {
|
||||||
|
bpf_tap(ifp, bpf_buf, len);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||||
|
if (m == NULL) {
|
||||||
|
ifp->if_ierrors++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MCLGET(m, M_DONTWAIT);
|
||||||
|
if (!(m->m_flags & M_EXT)) {
|
||||||
|
m_freem(m);
|
||||||
|
ifp->if_ierrors++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m->m_pkthdr.rcvif = ifp;
|
||||||
|
/* Read Ethenet encapsulated packet */
|
||||||
|
|
||||||
#ifdef ANCACHE
|
#ifdef ANCACHE
|
||||||
/* Read NIC frame header */
|
/* Read NIC frame header */
|
||||||
if (an_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) {
|
if (an_read_data(sc, id, 0, (caddr_t) & rx_frame, sizeof(rx_frame))) {
|
||||||
ifp->if_ierrors++;
|
ifp->if_ierrors++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Read in the 802_3 frame header */
|
/* Read in the 802_3 frame header */
|
||||||
if (an_read_data(sc, id, 0x34, (caddr_t)&rx_frame_802_3,
|
if (an_read_data(sc, id, 0x34, (caddr_t) & rx_frame_802_3,
|
||||||
sizeof(rx_frame_802_3))) {
|
sizeof(rx_frame_802_3))) {
|
||||||
ifp->if_ierrors++;
|
ifp->if_ierrors++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (rx_frame_802_3.an_rx_802_3_status != 0) {
|
||||||
|
ifp->if_ierrors++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Check for insane frame length */
|
||||||
|
if (rx_frame_802_3.an_rx_802_3_payload_len > MCLBYTES) {
|
||||||
|
ifp->if_ierrors++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m->m_pkthdr.len = m->m_len =
|
||||||
|
rx_frame_802_3.an_rx_802_3_payload_len + 12;
|
||||||
|
|
||||||
if (rx_frame_802_3.an_rx_802_3_status != 0) {
|
eh = mtod(m, struct ether_header *);
|
||||||
ifp->if_ierrors++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for insane frame length */
|
bcopy((char *)&rx_frame_802_3.an_rx_dst_addr,
|
||||||
if (rx_frame_802_3.an_rx_802_3_payload_len > MCLBYTES) {
|
(char *)&eh->ether_dhost, ETHER_ADDR_LEN);
|
||||||
ifp->if_ierrors++;
|
bcopy((char *)&rx_frame_802_3.an_rx_src_addr,
|
||||||
return;
|
(char *)&eh->ether_shost, ETHER_ADDR_LEN);
|
||||||
}
|
|
||||||
|
|
||||||
m->m_pkthdr.len = m->m_len =
|
/* in mbuf header type is just before payload */
|
||||||
rx_frame_802_3.an_rx_802_3_payload_len + 12;
|
error = an_read_data(sc, id, 0x44, (caddr_t)&(eh->ether_type),
|
||||||
|
rx_frame_802_3.an_rx_802_3_payload_len);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
bcopy((char *)&rx_frame_802_3.an_rx_dst_addr,
|
m_freem(m);
|
||||||
(char *)&eh->ether_dhost, ETHER_ADDR_LEN);
|
ifp->if_ierrors++;
|
||||||
bcopy((char *)&rx_frame_802_3.an_rx_src_addr,
|
return;
|
||||||
(char *)&eh->ether_shost, ETHER_ADDR_LEN);
|
}
|
||||||
|
ifp->if_ipackets++;
|
||||||
|
|
||||||
/* in mbuf header type is just before payload */
|
/* Receive packet. */
|
||||||
error = an_read_data(sc, id, 0x44, (caddr_t)&(eh->ether_type),
|
m_adj(m, sizeof(struct ether_header));
|
||||||
rx_frame_802_3.an_rx_802_3_payload_len);
|
|
||||||
|
|
||||||
if (error != 0) {
|
|
||||||
m_freem(m);
|
|
||||||
ifp->if_ierrors++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ifp->if_ipackets++;
|
|
||||||
|
|
||||||
/* Receive packet. */
|
|
||||||
m_adj(m, sizeof(struct ether_header));
|
|
||||||
#ifdef ANCACHE
|
#ifdef ANCACHE
|
||||||
an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength);
|
an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength);
|
||||||
#endif
|
#endif
|
||||||
ether_input(ifp, eh, m);
|
ether_input(ifp, eh, m);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void an_txeof(sc, status)
|
static void an_txeof(sc, status)
|
||||||
@ -517,10 +652,6 @@ static void an_txeof(sc, status)
|
|||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
int id, i;
|
int id, i;
|
||||||
|
|
||||||
/* TX DONE enable lan monitor DJA
|
|
||||||
an_enable_sniff();
|
|
||||||
*/
|
|
||||||
|
|
||||||
ifp = &sc->arpcom.ac_if;
|
ifp = &sc->arpcom.ac_if;
|
||||||
|
|
||||||
ifp->if_timer = 0;
|
ifp->if_timer = 0;
|
||||||
@ -1025,27 +1156,38 @@ static void an_setdef(sc, areq)
|
|||||||
sc->an_tx_rate = sp->an_val;
|
sc->an_tx_rate = sp->an_val;
|
||||||
break;
|
break;
|
||||||
case AN_RID_WEP_TEMP:
|
case AN_RID_WEP_TEMP:
|
||||||
/* Disable the MAC. */
|
|
||||||
an_cmd(sc, AN_CMD_DISABLE, 0);
|
|
||||||
|
|
||||||
/* Just write the Key, we don't want to save it */
|
|
||||||
an_write_record(sc, (struct an_ltv_gen *)areq);
|
|
||||||
|
|
||||||
/* Turn the MAC back on. */
|
|
||||||
an_cmd(sc, AN_CMD_ENABLE, 0);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case AN_RID_WEP_PERM:
|
case AN_RID_WEP_PERM:
|
||||||
|
|
||||||
/* Disable the MAC. */
|
/* Disable the MAC. */
|
||||||
an_cmd(sc, AN_CMD_DISABLE, 0);
|
an_cmd(sc, AN_CMD_DISABLE, 0);
|
||||||
|
|
||||||
/* Just write the Key, the card will save it in this mode */
|
/* Write the key */
|
||||||
an_write_record(sc, (struct an_ltv_gen *)areq);
|
an_write_record(sc, (struct an_ltv_gen *)areq);
|
||||||
|
|
||||||
/* Turn the MAC back on. */
|
/* Turn the MAC back on. */
|
||||||
an_cmd(sc, AN_CMD_ENABLE, 0);
|
an_cmd(sc, AN_CMD_ENABLE, 0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case AN_RID_MONITOR_MODE:
|
||||||
|
cfg = (struct an_ltv_genconfig *)areq;
|
||||||
|
bpfdetach(ifp);
|
||||||
|
if (ng_ether_detach_p != NULL)
|
||||||
|
(*ng_ether_detach_p) (ifp);
|
||||||
|
sc->an_monitor = cfg->an_len;
|
||||||
|
|
||||||
|
if (sc->an_monitor & AN_MONITOR){
|
||||||
|
if (sc->an_monitor & AN_MONITOR_AIRONET_HEADER){
|
||||||
|
bpfattach(ifp, DLT_AIRONET_HEADER,
|
||||||
|
sizeof(struct ether_header));
|
||||||
|
} else {
|
||||||
|
bpfattach(ifp, DLT_IEEE802_11,
|
||||||
|
sizeof(struct ether_header));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bpfattach(ifp, DLT_EN10MB,
|
||||||
|
sizeof(struct ether_header));
|
||||||
|
if (ng_ether_attach_p != NULL)
|
||||||
|
(*ng_ether_attach_p) (ifp);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("an%d: unknown RID: %x\n", sc->an_unit, areq->an_type);
|
printf("an%d: unknown RID: %x\n", sc->an_unit, areq->an_type);
|
||||||
@ -1062,16 +1204,21 @@ static void an_setdef(sc, areq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We can't change the NIC configuration while the MAC is enabled,
|
* Derived from Linux driver to enable promiscious mode.
|
||||||
* so in order to turn on RX monitor mode, we have to turn the MAC
|
|
||||||
* off first.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void an_promisc(sc, promisc)
|
static void an_promisc(sc, promisc)
|
||||||
struct an_softc *sc;
|
struct an_softc *sc;
|
||||||
int promisc;
|
int promisc;
|
||||||
{
|
{
|
||||||
an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0);
|
if(sc->an_was_monitor)
|
||||||
|
an_reset(sc);
|
||||||
|
if (sc->an_monitor ||sc->an_was_monitor )
|
||||||
|
an_init(sc);
|
||||||
|
|
||||||
|
sc->an_was_monitor = sc->an_monitor;
|
||||||
|
an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1634,13 +1781,19 @@ static void an_init(xsc)
|
|||||||
if (ifp->if_flags & IFF_MULTICAST)
|
if (ifp->if_flags & IFF_MULTICAST)
|
||||||
sc->an_config.an_rxmode = AN_RXMODE_BC_MC_ADDR;
|
sc->an_config.an_rxmode = AN_RXMODE_BC_MC_ADDR;
|
||||||
|
|
||||||
/* Initialize promisc mode. */
|
if (ifp->if_flags & IFF_PROMISC) {
|
||||||
/* Kills card DJA can't TX packet in sniff mode
|
if (sc->an_monitor & AN_MONITOR) {
|
||||||
if (ifp->if_flags & IFF_PROMISC)
|
if (sc->an_monitor & AN_MONITOR_ANY_BSS) {
|
||||||
sc->an_config.an_rxmode |= AN_RXMODE_LAN_MONITOR_CURBSS;
|
sc->an_config.an_rxmode |=
|
||||||
*/
|
AN_RXMODE_80211_MONITOR_ANYBSS |
|
||||||
|
AN_RXMODE_NO_8023_HEADER;
|
||||||
sc->an_rxmode = sc->an_config.an_rxmode;
|
} else {
|
||||||
|
sc->an_config.an_rxmode |=
|
||||||
|
AN_RXMODE_80211_MONITOR_CURBSS |
|
||||||
|
AN_RXMODE_NO_8023_HEADER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the ssid list */
|
/* Set the ssid list */
|
||||||
sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
|
sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
|
||||||
@ -1713,6 +1866,15 @@ static void an_start(ifp)
|
|||||||
if (!sc->an_associated)
|
if (!sc->an_associated)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (sc->an_monitor && (ifp->if_flags & IFF_PROMISC)) {
|
||||||
|
for(;;) {
|
||||||
|
IF_DEQUEUE(&ifp->if_snd, m0);
|
||||||
|
if (m0 == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
idx = sc->an_rdata.an_tx_prod;
|
idx = sc->an_rdata.an_tx_prod;
|
||||||
bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3));
|
bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3));
|
||||||
|
|
||||||
|
@ -96,6 +96,8 @@
|
|||||||
.Nm
|
.Nm
|
||||||
.Fl i Ar iface Fl r Ar RTS threshold
|
.Fl i Ar iface Fl r Ar RTS threshold
|
||||||
.Nm
|
.Nm
|
||||||
|
.Fl i Ar iface Fl M Ar 0-15 (set monitor mode)
|
||||||
|
.Nm
|
||||||
.Fl h
|
.Fl h
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
@ -394,6 +396,22 @@ need to be retransmitted instead of the whole packet.
|
|||||||
The fragmentation
|
The fragmentation
|
||||||
threshold can be anything from 64 to 2312 bytes.
|
threshold can be anything from 64 to 2312 bytes.
|
||||||
The default is 2312.
|
The default is 2312.
|
||||||
|
.It Fl i Ar iface Fl M Ar 0-15
|
||||||
|
Set monitor mode via bit mask, meaning:
|
||||||
|
.Bl -tag -offset indent -compact -width 0x000000
|
||||||
|
.Em "Bit Mask Meaning"
|
||||||
|
.It 0
|
||||||
|
to not dump 802.11 packet.
|
||||||
|
.It 1
|
||||||
|
to enable 802.11 monitor.
|
||||||
|
.It 2
|
||||||
|
to monitor any SSID.
|
||||||
|
.It 4
|
||||||
|
to not skip beacons, monitor beacons produces a high system load.
|
||||||
|
.It 8
|
||||||
|
to enable full Aironet header returned via BPF.
|
||||||
|
Note it appears that a SSID must be set.
|
||||||
|
.El
|
||||||
.It Fl i Ar iface Fl r Ar RTS threshold
|
.It Fl i Ar iface Fl r Ar RTS threshold
|
||||||
Set the RTS/CTS threshold for a given interface.
|
Set the RTS/CTS threshold for a given interface.
|
||||||
This controls the
|
This controls the
|
||||||
|
@ -125,6 +125,7 @@ int main __P((int, char **));
|
|||||||
#define ACT_SET_KEY_TYPE 34
|
#define ACT_SET_KEY_TYPE 34
|
||||||
#define ACT_SET_KEYS 35
|
#define ACT_SET_KEYS 35
|
||||||
#define ACT_ENABLE_TX_KEY 36
|
#define ACT_ENABLE_TX_KEY 36
|
||||||
|
#define ACT_SET_MONITOR_MODE 37
|
||||||
|
|
||||||
static void an_getval(iface, areq)
|
static void an_getval(iface, areq)
|
||||||
const char *iface;
|
const char *iface;
|
||||||
@ -283,6 +284,7 @@ static void an_dumpstatus(iface)
|
|||||||
an_printhex((char *)&sts->an_errcode, 1);
|
an_printhex((char *)&sts->an_errcode, 1);
|
||||||
printf("\nSignal quality:\t\t");
|
printf("\nSignal quality:\t\t");
|
||||||
an_printhex((char *)&sts->an_cur_signal_quality, 1);
|
an_printhex((char *)&sts->an_cur_signal_quality, 1);
|
||||||
|
printf("\nSignal strength:\t[ %d%% ]",sts->an_normalized_rssi);
|
||||||
/*
|
/*
|
||||||
* XXX: This uses the old definition of the rate field (units of
|
* XXX: This uses the old definition of the rate field (units of
|
||||||
* 500kbps). Technically the new definition is that this field
|
* 500kbps). Technically the new definition is that this field
|
||||||
@ -839,6 +841,7 @@ static void usage(p)
|
|||||||
fprintf(stderr, "\t%s -i iface -c val (set ad-hoc channel)\n", p);
|
fprintf(stderr, "\t%s -i iface -c val (set ad-hoc channel)\n", p);
|
||||||
fprintf(stderr, "\t%s -i iface -f val (set frag threshold)\n", p);
|
fprintf(stderr, "\t%s -i iface -f val (set frag threshold)\n", p);
|
||||||
fprintf(stderr, "\t%s -i iface -r val (set RTS threshold)\n", p);
|
fprintf(stderr, "\t%s -i iface -r val (set RTS threshold)\n", p);
|
||||||
|
fprintf(stderr, "\t%s -i iface -M 0-15 (set monitor mode)\n", p);
|
||||||
#ifdef ANCACHE
|
#ifdef ANCACHE
|
||||||
fprintf(stderr, "\t%s -i iface -Q print signal quality cache\n", p);
|
fprintf(stderr, "\t%s -i iface -Q print signal quality cache\n", p);
|
||||||
fprintf(stderr, "\t%s -i iface -Z zero out signal cache\n", p);
|
fprintf(stderr, "\t%s -i iface -Z zero out signal cache\n", p);
|
||||||
@ -977,6 +980,10 @@ static void an_setconfig(iface, act, arg)
|
|||||||
cfg->an_authtype = (cfg->an_authtype & ~AN_AUTHTYPE_MASK)
|
cfg->an_authtype = (cfg->an_authtype & ~AN_AUTHTYPE_MASK)
|
||||||
| atoi(arg);
|
| atoi(arg);
|
||||||
break;
|
break;
|
||||||
|
case ACT_SET_MONITOR_MODE:
|
||||||
|
areq.an_type = AN_RID_MONITOR_MODE;
|
||||||
|
cfg->an_len = atoi(arg); /* mode is put in length */
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
errx(1, "unknown action");
|
errx(1, "unknown action");
|
||||||
break;
|
break;
|
||||||
@ -1282,18 +1289,20 @@ static void an_readkeyinfo(iface)
|
|||||||
|
|
||||||
printf("WEP Key status:\n");
|
printf("WEP Key status:\n");
|
||||||
areq.an_type = AN_RID_WEP_TEMP; /* read first key */
|
areq.an_type = AN_RID_WEP_TEMP; /* read first key */
|
||||||
for(i=0; i<4; i++){
|
for(i=0; i<5; i++){
|
||||||
areq.an_len = sizeof(struct an_ltv_key);
|
areq.an_len = sizeof(struct an_ltv_key);
|
||||||
an_getval(iface, &areq);
|
an_getval(iface, &areq);
|
||||||
|
if(k->kindex == 0xffff)
|
||||||
|
break;
|
||||||
switch (k->klen){
|
switch (k->klen){
|
||||||
case 0:
|
case 0:
|
||||||
printf("\tKey %d is unset\n",i);
|
printf("\tKey %d is unset\n",k->kindex);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
printf("\tKey %d is set 40 bits\n",i);
|
printf("\tKey %d is set 40 bits\n",k->kindex);
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
printf("\tKey %d is set 128 bits\n",i);
|
printf("\tKey %d is set 128 bits\n",k->kindex);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("\tWEP Key %d has an unknown size %d\n",
|
printf("\tWEP Key %d has an unknown size %d\n",
|
||||||
@ -1369,7 +1378,7 @@ int main(argc, argv)
|
|||||||
opterr = 1;
|
opterr = 1;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv,
|
while ((ch = getopt(argc, argv,
|
||||||
"ANISCTht:a:e:o:s:n:v:d:j:b:c:r:p:w:m:l:k:K:W:QZ")) != -1) {
|
"ANISCTht:a:e:o:s:n:v:d:j:b:c:r:p:w:m:l:k:K:W:QZM:")) != -1) {
|
||||||
switch(ch) {
|
switch(ch) {
|
||||||
case 'Z':
|
case 'Z':
|
||||||
#ifdef ANCACHE
|
#ifdef ANCACHE
|
||||||
@ -1532,6 +1541,10 @@ int main(argc, argv)
|
|||||||
act = ACT_SET_WAKE_DURATION;
|
act = ACT_SET_WAKE_DURATION;
|
||||||
arg = optarg;
|
arg = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'M':
|
||||||
|
act = ACT_SET_MONITOR_MODE;
|
||||||
|
arg = optarg;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
default:
|
default:
|
||||||
usage(p);
|
usage(p);
|
||||||
|
Loading…
Reference in New Issue
Block a user