ieee80211_monitor.c revision 193287
1188808Sgonzo/*-
2188808Sgonzo * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
3188808Sgonzo * All rights reserved.
4188808Sgonzo *
5188808Sgonzo * Redistribution and use in source and binary forms, with or without
6188808Sgonzo * modification, are permitted provided that the following conditions
7188808Sgonzo * are met:
8188808Sgonzo * 1. Redistributions of source code must retain the above copyright
9188808Sgonzo *    notice, this list of conditions and the following disclaimer.
10188808Sgonzo * 2. Redistributions in binary form must reproduce the above copyright
11188808Sgonzo *    notice, this list of conditions and the following disclaimer in the
12188808Sgonzo *    documentation and/or other materials provided with the distribution.
13188808Sgonzo *
14188808Sgonzo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15188808Sgonzo * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16188808Sgonzo * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17188808Sgonzo * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18188808Sgonzo * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19188808Sgonzo * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20188808Sgonzo * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21188808Sgonzo * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22188808Sgonzo * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23188808Sgonzo * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24188808Sgonzo */
25188808Sgonzo
26188808Sgonzo#include <sys/cdefs.h>
27188808Sgonzo#ifdef __FreeBSD__
28188808Sgonzo__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_monitor.c 193287 2009-06-02 00:04:10Z sam $");
29188808Sgonzo#endif
30188808Sgonzo
31188808Sgonzo/*
32188808Sgonzo * IEEE 802.11 Monitor mode support.
33188808Sgonzo */
34192783Sgonzo#include "opt_inet.h"
35192783Sgonzo#include "opt_wlan.h"
36192783Sgonzo
37192783Sgonzo#include <sys/param.h>
38188808Sgonzo#include <sys/systm.h>
39188808Sgonzo#include <sys/mbuf.h>
40188808Sgonzo#include <sys/malloc.h>
41188808Sgonzo#include <sys/kernel.h>
42188808Sgonzo
43188808Sgonzo#include <sys/socket.h>
44188808Sgonzo#include <sys/sockio.h>
45188808Sgonzo#include <sys/endian.h>
46188808Sgonzo#include <sys/errno.h>
47188808Sgonzo#include <sys/proc.h>
48209802Sadrian#include <sys/sysctl.h>
49188808Sgonzo
50188808Sgonzo#include <net/if.h>
51188808Sgonzo#include <net/if_media.h>
52188808Sgonzo#include <net/if_llc.h>
53188808Sgonzo#include <net/ethernet.h>
54188808Sgonzo
55188808Sgonzo#include <net/bpf.h>
56188808Sgonzo
57188808Sgonzo#include <net80211/ieee80211_var.h>
58188808Sgonzo#include <net80211/ieee80211_monitor.h>
59188808Sgonzo
60188808Sgonzostatic void monitor_vattach(struct ieee80211vap *);
61188808Sgonzostatic int monitor_newstate(struct ieee80211vap *, enum ieee80211_state, int);
62188808Sgonzostatic int monitor_input(struct ieee80211_node *ni, struct mbuf *m,
63188808Sgonzo	int rssi, int nf);
64188808Sgonzo
65188808Sgonzovoid
66188808Sgonzoieee80211_monitor_attach(struct ieee80211com *ic)
67188808Sgonzo{
68188808Sgonzo	ic->ic_vattach[IEEE80211_M_MONITOR] = monitor_vattach;
69188808Sgonzo}
70188808Sgonzo
71188808Sgonzovoid
72188808Sgonzoieee80211_monitor_detach(struct ieee80211com *ic)
73188808Sgonzo{
74188808Sgonzo}
75188808Sgonzo
76188808Sgonzostatic void
77188808Sgonzomonitor_vdetach(struct ieee80211vap *vap)
78188808Sgonzo{
79188808Sgonzo}
80188808Sgonzo
81188808Sgonzostatic void
82211477Sadrianmonitor_vattach(struct ieee80211vap *vap)
83188808Sgonzo{
84188808Sgonzo	vap->iv_newstate = monitor_newstate;
85188808Sgonzo	vap->iv_input = monitor_input;
86188808Sgonzo	vap->iv_opdetach = monitor_vdetach;
87188808Sgonzo}
88188808Sgonzo
89188808Sgonzo/*
90188808Sgonzo * IEEE80211_M_MONITOR vap state machine handler.
91188808Sgonzo */
92188808Sgonzostatic int
93188808Sgonzomonitor_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
94188808Sgonzo{
95188808Sgonzo	struct ieee80211com *ic = vap->iv_ic;
96188808Sgonzo	enum ieee80211_state ostate;
97188808Sgonzo
98188808Sgonzo	IEEE80211_LOCK_ASSERT(ic);
99188808Sgonzo
100199234Sgonzo	ostate = vap->iv_state;
101188808Sgonzo	IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n",
102188808Sgonzo	    __func__, ieee80211_state_name[ostate],
103188808Sgonzo	    ieee80211_state_name[nstate], arg);
104188808Sgonzo	vap->iv_state = nstate;			/* state transition */
105188808Sgonzo	if (nstate == IEEE80211_S_RUN) {
106188808Sgonzo		switch (ostate) {
107188808Sgonzo		case IEEE80211_S_INIT:
108188808Sgonzo			ieee80211_create_ibss(vap, ic->ic_curchan);
109192821Sgonzo			break;
110198667Sgonzo		default:
111192821Sgonzo			break;
112194059Sgonzo		}
113188808Sgonzo		/*
114188808Sgonzo		 * NB: this shouldn't be here but many people use
115188808Sgonzo		 * monitor mode for raw packets; once we switch
116188808Sgonzo		 * them over to adhoc demo mode remove this.
117188808Sgonzo		 */
118198667Sgonzo		ieee80211_node_authorize(vap->iv_bss);
119188808Sgonzo	}
120188808Sgonzo	return 0;
121188808Sgonzo}
122188808Sgonzo
123188808Sgonzo/*
124199234Sgonzo * Process a received frame in monitor mode.
125199234Sgonzo */
126199234Sgonzostatic int
127199234Sgonzomonitor_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
128199234Sgonzo{
129199234Sgonzo	struct ieee80211vap *vap = ni->ni_vap;
130188808Sgonzo	struct ifnet *ifp = vap->iv_ifp;
131188808Sgonzo
132188808Sgonzo	ifp->if_ipackets++;
133188808Sgonzo
134188808Sgonzo	if (ieee80211_radiotap_active_vap(vap))
135188808Sgonzo		ieee80211_radiotap_rx(vap, m);
136188808Sgonzo	m_freem(m);
137188808Sgonzo	return -1;
138188808Sgonzo}
139188808Sgonzo