📄 ieee80211_monitor.c
字号:
/*- * Copyright (c) 2005 John Bicket * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $Id: ieee80211_monitor.c 3298 2008-01-29 02:21:47Z br1 $ */#ifndef EXPORT_SYMTAB#define EXPORT_SYMTAB#endif/* * IEEE 802.11 monitor mode */#ifndef AUTOCONF_INCLUDED#include <linux/config.h>#endif#include <linux/version.h>#include <linux/module.h>#include <linux/kmod.h>#include <linux/init.h>#include <linux/skbuff.h>#include <linux/sysctl.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/if_vlan.h>#include <net/iw_handler.h>#include <linux/wireless.h>#include <linux/if_arp.h> /* XXX for ARPHRD_* */#include <asm/uaccess.h>#include "if_media.h"#include "if_ethersubr.h"#include <net80211/ieee80211_var.h>#include <net80211/ieee80211_monitor.h>#include <ath/if_athvar.h>static intratecode_to_dot11(int ratecode){ switch (ratecode) { /* a */ case 0x0b: return 12; case 0x0f: return 18; case 0x0a: return 24; case 0x0e: return 36; case 0x09: return 48; case 0x0d: return 72; case 0x08: return 96; case 0x0c: return 108; case 0x1b: return 2; case 0x1a: return 4; case 0x1e: return 4; case 0x19: return 11; case 0x1d: return 11; case 0x18: return 22; case 0x1c: return 22; } return 0;}struct ar5212_openbsd_desc { /* * tx_control_0 */ u_int32_t frame_len:12; u_int32_t reserved_12_15:4; u_int32_t xmit_power:6; u_int32_t rts_cts_enable:1; u_int32_t veol:1; u_int32_t clear_dest_mask:1; u_int32_t ant_mode_xmit:4; u_int32_t inter_req:1; u_int32_t encrypt_key_valid:1; u_int32_t cts_enable:1; u_int32_t r1; /* * tx_control_2 */ u_int32_t rts_duration:15; u_int32_t duration_update_enable:1; u_int32_t xmit_tries0:4; u_int32_t xmit_tries1:4; u_int32_t xmit_tries2:4; u_int32_t xmit_tries3:4; /* * tx_control_3 */ u_int32_t xmit_rate0:5; u_int32_t xmit_rate1:5; u_int32_t xmit_rate2:5; u_int32_t xmit_rate3:5; u_int32_t rts_cts_rate:5; u_int32_t reserved_25_31:7;};voidieee80211_monitor_encap(struct ieee80211vap *vap, struct sk_buff *skb) { struct ieee80211_cb *cb = (struct ieee80211_cb *) skb->cb; struct ieee80211_phy_params *ph = (struct ieee80211_phy_params *) (skb->cb + sizeof(struct ieee80211_cb)); cb->flags = M_RAW; cb->ni = NULL; cb->next = NULL; memset(ph, 0, sizeof(struct ieee80211_phy_params)); /* send at a static rate if it is configured */ ph->rate0 = vap->iv_fixed_rate > 0 ? vap->iv_fixed_rate : 2; /* don't retry control packets */ ph->try0 = 11; ph->power = 60; switch (skb->dev->type) { case ARPHRD_IEEE80211: { struct ieee80211_frame *wh = (struct ieee80211_frame *) skb->data; if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) ph->try0 = 1; break; } case ARPHRD_IEEE80211_PRISM: { struct ieee80211_frame *wh = NULL; wlan_ng_prism2_header *p2h = (wlan_ng_prism2_header *) skb->data; /* does it look like there is a prism header here? */ if (skb->len > sizeof (wlan_ng_prism2_header) && p2h->msgcode == DIDmsg_lnxind_wlansniffrm && p2h->rate.did == DIDmsg_lnxind_wlansniffrm_rate) { ph->rate0 = p2h->rate.data; skb_pull(skb, sizeof(wlan_ng_prism2_header)); } wh = (struct ieee80211_frame *) skb->data; if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) ph->try0 = 1; break; } case ARPHRD_IEEE80211_RADIOTAP: { struct ieee80211_frame *wh = NULL; struct ieee80211_radiotap_header *rh = (struct ieee80211_radiotap_header *)skb->data; u_int32_t present, present_ext; u_int16_t len; u_int8_t *start = skb->data + sizeof(struct ieee80211_radiotap_header); u_int8_t *p = start; u_int8_t *end = skb->data + skb->len; u_int8_t bit, flags = 0; if (skb->len < sizeof(*rh) || rh->it_version != 0) break; present_ext = present = le32_to_cpu(rh->it_present); len = le16_to_cpu(rh->it_len); if (skb->len < len) break; /* skip the chain of additional bitmaps following it_present */ while (present_ext & (1 << IEEE80211_RADIOTAP_EXT)) { if (p+4 > end) { /* An extended bitmap would now follow, but there is * no place for it. Stop parsing. */ present = 0; break; } present_ext = le32_to_cpu(*(__le32 *)p); p += 4; } for (bit = 0; present && p < end; present >>= 1, bit++) { if ((present & 1) == 0) continue; switch (bit) { case IEEE80211_RADIOTAP_RATE: ph->rate0 = *p; p++; break; case IEEE80211_RADIOTAP_DBM_TX_POWER: ph->power = *p; p++; break; case IEEE80211_RADIOTAP_FLAGS: flags = *p; p++; break; case IEEE80211_RADIOTAP_DB_ANTSIGNAL: case IEEE80211_RADIOTAP_DB_ANTNOISE: case IEEE80211_RADIOTAP_ANTENNA: case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: case IEEE80211_RADIOTAP_DBM_ANTNOISE: /* 8-bit */ p++; break; case IEEE80211_RADIOTAP_FHSS: /* 2 x 8-bit */ p += 2; break; case IEEE80211_RADIOTAP_LOCK_QUALITY: case IEEE80211_RADIOTAP_TX_ATTENUATION: case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: /* 16-bit */ p = start + roundup(p - start, 2) + 2; break; case IEEE80211_RADIOTAP_CHANNEL: /* 2 x 16-bit */ p = start + roundup(p - start, 2) + 4; break; case IEEE80211_RADIOTAP_TSFT: /* 64-bit */ p = start + roundup(p - start, 8) + 8; break; case IEEE80211_RADIOTAP_DATA_RETRIES: ph->try0 = *p + 1; p++; break; default: present = 0; break; } } skb_pull(skb, len); if (flags & IEEE80211_RADIOTAP_F_FCS) /* Remove FCS from the end of frames to transmit */ skb_trim(skb, skb->len - IEEE80211_CRC_LEN); wh = (struct ieee80211_frame *)skb->data; if (!ph->try0 && (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) ph->try0 = 1; break; } case ARPHRD_IEEE80211_ATHDESC: { if (skb->len > ATHDESC_HEADER_SIZE) { struct ar5212_openbsd_desc *desc = (struct ar5212_openbsd_desc *) (skb->data + 8); ph->power = desc->xmit_power; ph->rate0 = ratecode_to_dot11(desc->xmit_rate0); ph->rate1 = ratecode_to_dot11(desc->xmit_rate1); ph->rate2 = ratecode_to_dot11(desc->xmit_rate2); ph->rate3 = ratecode_to_dot11(desc->xmit_rate3); ph->try0 = desc->xmit_tries0; ph->try1 = desc->xmit_tries1; ph->try2 = desc->xmit_tries2; ph->try3 = desc->xmit_tries3; skb_pull(skb, ATHDESC_HEADER_SIZE); } break; } default: break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -