⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ieee80211_monitor.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
voidieee80211_input_monitor(struct ieee80211com *ic, struct sk_buff *skb,	const struct ath_buf *bf, int tx, u_int64_t mactime, struct ath_softc *sc){	struct ieee80211vap *vap, *next;	struct ath_desc *ds = bf->bf_desc;	int noise = 0, antenna = 0, ieeerate = 0;	u_int32_t rssi = 0;	u_int8_t pkttype = 0;	if (tx) {		rssi = bf->bf_dsstatus.ds_txstat.ts_rssi;		antenna = bf->bf_dsstatus.ds_txstat.ts_antenna;		ieeerate = sc->sc_hwmap[bf->bf_dsstatus.ds_txstat.ts_rate].ieeerate;	} else {		rssi = bf->bf_dsstatus.ds_rxstat.rs_rssi;		antenna = bf->bf_dsstatus.ds_rxstat.rs_antenna;		ieeerate = sc->sc_hwmap[bf->bf_dsstatus.ds_rxstat.rs_rate].ieeerate;	}	noise = bf->bf_channoise;	/* XXX locking */	for (vap = TAILQ_FIRST(&ic->ic_vaps); vap != NULL; vap = next) {		struct sk_buff *skb1;		struct net_device *dev = vap->iv_dev;		struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data;		u_int8_t dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;		next = TAILQ_NEXT(vap, iv_next);		/* If we have rx'd an error frame... */		if (!tx && bf->bf_dsstatus.ds_rxstat.rs_status != 0) {			/* Discard PHY errors if necessary */			if (bf->bf_dsstatus.ds_rxstat.rs_status & HAL_RXERR_PHY) {				if (vap->iv_monitor_phy_errors == 0) continue;			}			/* Discard CRC errors if necessary */			if (bf->bf_dsstatus.ds_rxstat.rs_status & HAL_RXERR_CRC) {				if (vap->iv_monitor_crc_errors == 0) continue;			}			/* Accept PHY, CRC and decrypt errors. Discard the rest. */			if (bf->bf_dsstatus.ds_rxstat.rs_status &~					(HAL_RXERR_DECRYPT | HAL_RXERR_MIC |					 HAL_RXERR_PHY | HAL_RXERR_CRC))				continue;			/* We can't use addr1 to determine direction at this point */			pkttype = PACKET_HOST;		} else {			/* 			 * The frame passed its CRC, so we can rely			 * on the contents of the frame to set pkttype.			 */			if (tx)				pkttype = PACKET_OUTGOING;			else if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {				if (IEEE80211_ADDR_EQ(wh->i_addr1, dev->broadcast))					pkttype = PACKET_BROADCAST;				else					pkttype = PACKET_MULTICAST;			} else				pkttype = PACKET_HOST;		}		if (vap->iv_opmode != IEEE80211_M_MONITOR ||		    vap->iv_state != IEEE80211_S_RUN)			continue;		if (vap->iv_monitor_nods_only &&		    dir != IEEE80211_FC1_DIR_NODS) {			/* don't rx fromds, tods, or dstods packets */			continue;		}				if (skb_headroom(skb) < IEEE80211_MON_MAXHDROOM)			skb1 = skb_copy_expand(skb, IEEE80211_MON_MAXHDROOM,					0, GFP_ATOMIC);		else			skb1 = skb_copy(skb, GFP_ATOMIC);		if (skb1 == NULL) {			/* XXX stat+msg */			continue;		}		ieee80211_skb_copy_noderef(skb, skb1);		if (vap->iv_monitor_txf_len && tx) {			/* truncate transmit feedback packets */			skb_trim(skb1, vap->iv_monitor_txf_len);			skb_reset_network_header(skb1);		}		switch (vap->iv_dev->type) {		case ARPHRD_IEEE80211:			break;		case ARPHRD_IEEE80211_PRISM: {			struct wlan_ng_prism2_header *ph;			if (skb_headroom(skb1) < sizeof(struct wlan_ng_prism2_header)) {				ieee80211_dev_kfree_skb(&skb1);				break;			}			ph = (struct wlan_ng_prism2_header *)				skb_push(skb1, sizeof(struct wlan_ng_prism2_header));			memset(ph, 0, sizeof(struct wlan_ng_prism2_header));			ph->msgcode = DIDmsg_lnxind_wlansniffrm;			ph->msglen = sizeof(struct wlan_ng_prism2_header);			strncpy(ph->devname, dev->name, sizeof(ph->devname));			ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;			ph->hosttime.status = 0;			ph->hosttime.len = 4;			ph->hosttime.data = jiffies;			/* Pass up tsf clock in mactime */			/* NB: the prism mactime field is 32bit, so we lose TSF precision here */			ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;			ph->mactime.status = 0;			ph->mactime.len = 4;			ph->mactime.data = mactime;			ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;			ph->istx.status = 0;			ph->istx.len = 4;			ph->istx.data = tx ? P80211ENUM_truth_true : P80211ENUM_truth_false;			ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;			ph->frmlen.status = 0;			ph->frmlen.len = 4;			ph->frmlen.data = skb->len;			ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;			ph->channel.status = 0;			ph->channel.len = 4;			ph->channel.data =				ieee80211_mhz2ieee(ic->ic_curchan->ic_freq,					ic->ic_curchan->ic_flags);			ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;			ph->rssi.status = 0;			ph->rssi.len = 4;			ph->rssi.data = rssi;			ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;			ph->noise.status = 0;			ph->noise.len = 4;			ph->noise.data = noise;			ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;			ph->signal.status = 0;			ph->signal.len = 4;			ph->signal.data = rssi + noise;			ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;			ph->rate.status = 0;			ph->rate.len = 4;			ph->rate.data = ieeerate;			break;		}		case ARPHRD_IEEE80211_RADIOTAP: {			if (tx) {				struct ath_tx_radiotap_header *th;				if (skb_headroom(skb1) < sizeof(struct ath_tx_radiotap_header)) {					printk("%s:%d %s\n", __FILE__, __LINE__, __func__);					ieee80211_dev_kfree_skb(&skb1);					break;				}				th = (struct ath_tx_radiotap_header *)skb_push(skb1,					sizeof(struct ath_tx_radiotap_header));				memset(th, 0, sizeof(struct ath_tx_radiotap_header));				th->wt_ihdr.it_version = 0;				th->wt_ihdr.it_len = cpu_to_le16(sizeof(struct ath_tx_radiotap_header));				th->wt_ihdr.it_present = cpu_to_le32(ATH_TX_RADIOTAP_PRESENT);				/* radiotap's TSF field is the full 64 bits, so we don't lose				 * any TSF precision when using radiotap */				th->wt_tsft = cpu_to_le64(mactime);				th->wt_flags = 0;				th->wt_rate = ieeerate;				th->wt_antenna = antenna;				th->wt_pad = 0;				if (bf->bf_dsstatus.ds_txstat.ts_status & HAL_TXERR_XRETRY)					th->wt_txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);				th->wt_dataretries = bf->bf_dsstatus.ds_txstat.ts_shortretry + bf->bf_dsstatus.ds_txstat.ts_longretry;			} else {				struct ath_rx_radiotap_header *th;				if (skb_headroom(skb1) < sizeof(struct ath_rx_radiotap_header)) {					printk("%s:%d %s\n", __FILE__, __LINE__, __func__);					ieee80211_dev_kfree_skb(&skb1);					break;				}				th = (struct ath_rx_radiotap_header *)skb_push(skb1,					sizeof(struct ath_rx_radiotap_header));				memset(th, 0, sizeof(struct ath_rx_radiotap_header));				th->wr_ihdr.it_version = 0;				th->wr_ihdr.it_len = cpu_to_le16(sizeof(struct ath_rx_radiotap_header));				th->wr_ihdr.it_present = cpu_to_le32(ATH_RX_RADIOTAP_PRESENT);				if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)					th->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;				if (bf->bf_dsstatus.ds_rxstat.rs_status & HAL_RXERR_CRC)					th->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;				if (skb->len >= IEEE80211_CRC_LEN)					th->wr_flags |= IEEE80211_RADIOTAP_F_FCS;				th->wr_rate = ieeerate;				th->wr_chan_freq = cpu_to_le16(ic->ic_curchan->ic_freq);				/* Define the channel flags for radiotap */				switch (sc->sc_curmode) {					case IEEE80211_MODE_11A:						th->wr_chan_flags =							cpu_to_le16(IEEE80211_CHAN_A);						break;					case IEEE80211_MODE_TURBO_A:						th->wr_chan_flags =							cpu_to_le16(IEEE80211_CHAN_TA);						break;					case IEEE80211_MODE_11B:						th->wr_chan_flags =							cpu_to_le16(IEEE80211_CHAN_B);						break;					case IEEE80211_MODE_11G:						th->wr_chan_flags =							cpu_to_le16(IEEE80211_CHAN_G);						break;					case IEEE80211_MODE_TURBO_G:						th->wr_chan_flags =							cpu_to_le16(IEEE80211_CHAN_TG);						break;					default:						th->wr_chan_flags = 0; /* unknown */						break;				}				th->wr_dbm_antnoise = (int8_t) noise;				th->wr_dbm_antsignal = 					th->wr_dbm_antnoise + rssi;				th->wr_antenna = antenna;				th->wr_antsignal = rssi;				th->wr_tsft = cpu_to_le64(mactime);			}			break;		}		case ARPHRD_IEEE80211_ATHDESC: {			if (skb_headroom(skb1) < ATHDESC_HEADER_SIZE) {				printk("%s:%d %s\n", __FILE__, 						__LINE__, __func__);				ieee80211_dev_kfree_skb(&skb1);				break;			}			memcpy(skb_push(skb1, ATHDESC_HEADER_SIZE), 					ds, ATHDESC_HEADER_SIZE);			break;		}		default:			break;		}		if (skb1 != NULL) {			if (!tx && (skb1->len >= IEEE80211_CRC_LEN) && 					(vap->iv_dev->type != 					 ARPHRD_IEEE80211_RADIOTAP)) {				/* Remove FCS from end of RX frames when				 * delivering to non-Radiotap VAPs. */				skb_trim(skb1, skb1->len - IEEE80211_CRC_LEN);			}			skb1->dev = dev; /* NB: deliver to wlanX */			skb_reset_mac_header(skb1);			skb1->ip_summed = CHECKSUM_NONE;			skb1->pkt_type = pkttype;			skb1->protocol = 				__constant_htons(0x0019); /* ETH_P_80211_RAW */			vap->iv_devstats.rx_packets++;			vap->iv_devstats.rx_bytes += skb1->len;			if (SKB_NI(skb1) != NULL)				ieee80211_unref_node(&SKB_NI(skb1));			if (netif_rx(skb1) == NET_RX_DROP)				vap->iv_devstats.rx_dropped++;			skb1 = NULL;		}	}}EXPORT_SYMBOL(ieee80211_input_monitor);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -