├── Makefile
├── Nexus5_Nougat
├── README.md
└── libnexmonkali.so
├── Nexus6P_Oreo
├── README.md
└── libnexmonkali.so
├── README.md
├── bcm_cfg.h
├── bcmdefs.h
├── bcmutils.h
├── bcmwifi_channels.h
├── libnexio.c
├── monitormode.h
├── nexioctls.h
├── nexmon.c
└── typedefs.h
/Makefile:
--------------------------------------------------------------------------------
1 | CC = gcc
2 |
3 | CFLAGS = -std=c99 -I./ -I/usr/include/libnl3
4 | LDFLAGS = -shared -fPIC -ldl libnexio.a
5 |
6 | all: libnexio.a libnexmonkali.so
7 |
8 | libnexmonkali.so: libnexio.a nexmon.c
9 | $(CC) -o libnexmonkali.so $(CFLAGS) nexmon.c $(LDFLAGS)
10 |
11 | libnexio.a: libnexio.c
12 | $(CC) -c libnexio.c
13 | ar rcs libnexio.a libnexio.o
14 |
15 | clean:
16 | rm libnexmonkali.so libnexio.a libnexio.o
17 |
18 | install:
19 | cp libnexmonkali.so /usr/lib/
20 | chmod 0755 /usr/lib/libnexmonkali.so
21 | chmod +x /usr/lib/libnexmonkali.so
22 |
23 | uninstall:
24 | rm /usr/lib/libnexmonkali.so
25 |
--------------------------------------------------------------------------------
/Nexus5_Nougat/README.md:
--------------------------------------------------------------------------------
1 | Pre-compiled .so, built for Nexus 5 running Android 7.1 Nougat ("razorloves" build), with NetHunter 2021.2.
2 |
3 | The stock version is found in `/system/lib/kalilibnexmon.so`.
4 |
--------------------------------------------------------------------------------
/Nexus5_Nougat/libnexmonkali.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoninNada/libnexmonkali/4abdc7673233eda5ca86125e2d333a86af2545ab/Nexus5_Nougat/libnexmonkali.so
--------------------------------------------------------------------------------
/Nexus6P_Oreo/README.md:
--------------------------------------------------------------------------------
1 | Pre-compiled .so, built for Nexus 6P running Android 8.1.0 Oreo, with NetHunter 2020.3.
2 |
3 | The stock version is found in `/system/lib64/kalilibnexmon.so`.
4 |
--------------------------------------------------------------------------------
/Nexus6P_Oreo/libnexmonkali.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoninNada/libnexmonkali/4abdc7673233eda5ca86125e2d333a86af2545ab/Nexus6P_Oreo/libnexmonkali.so
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # What is `libnexmonkali`?
2 | It's an alternate version of libnexmon.so from https://github.com/seemoo-lab/nexmon for building and usage in Kali Nethunter Chroot.
3 |
4 | It's a wrapper that will allow standard Linux wifi tools such as the `aircrack-ng` suite to use the onboard wifi interfaces on some mobile phones.
5 |
6 | There are prebuilt versions of `libnexmonkali.so` available in the repo for the Nexus 5 and Nexus 6P.
7 |
8 | # What's changed in this version from the stock NetHunter one?
9 | This is a replacement for the `kalilibnexmon.so` that currently ships in Kali NetHunter, that implements a few improvements.
10 |
11 | This version adds ioctl() support for SIOCSIWFREQ and SIOCGIWFREQ, meaning that programs that use ioctl calls will be able to directly get/set the channel of the onboard wifi instead of relying on the `nexutil` tool.
12 |
13 | Additionally, it adds a 50 millisecond delay after each injected frame, which seems to eliminate driver crashes when doing deauths with aireplay-ng.
14 |
15 | Now it's also intercepting `netlink` messages, which is a newer method for programs to tell drivers to do things like change wifi channels. The intent is to allow more programs to function with the non-standard wifi drivers found on the Nexus 5 and 6P. It's not a full implementation, but it helps some.
16 |
17 | # How does the `netlink` part work?
18 | We are intercepting the `nl_send_auto_complete` function that programs such as airodump-ng and kismet use to initiate a Netlink message, asking the kernel to tell the driver to change channels.
19 | We pass that message on to the kernel as usual, but also read the message and set the channel appropriately ourselves.
20 | Because this isn't the real driver, we won't send anything back to the program -- but airodump-ng and kismet don't bother to listen for replies anyway, so that's okay.
21 | Programs like `iw` do listen for a reply message, which we can't fake. They will complain that the channel change didn't work, but it actually did.
22 |
23 | ```
24 | root@kali:~# nexutil -k
25 | chanspec: 0x1006, 6
26 | root@kali:~# LD_PRELOAD=/root/libnexmonkali/libnexmonkali.so iw dev wlan0 set channel 36
27 | command failed: Operation not supported (-95)
28 | root@kali:~# nexutil -k
29 | chanspec: 0xd024, 36
30 | ```
31 |
32 |
33 | # Steps to Build
34 | Do the following from within your Kali NetHunter chroot environment.
35 |
36 | Clone the repo:
37 | `git clone https://github.com/dracode/libnexmonkali`
38 |
39 | Install dependencies:
40 | `apt install libnl-3-dev`
41 |
42 | Build:
43 | `make`
44 |
45 | Install:
46 | `make install`
47 |
48 | Use:
49 | `LD_PRELOAD=/path/to/libnexmonkali.so airodump-ng wlan0`
50 |
51 |
--------------------------------------------------------------------------------
/bcm_cfg.h:
--------------------------------------------------------------------------------
1 | /*
2 | * BCM common config options
3 | *
4 | * Copyright (C) 1999-2013, Broadcom Corporation
5 | *
6 | * Unless you and Broadcom execute a separate written software license
7 | * agreement governing use of this software, this software is licensed to you
8 | * under the terms of the GNU General Public License version 2 (the "GPL"),
9 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10 | * following added to such license:
11 | *
12 | * As a special exception, the copyright holders of this software give you
13 | * permission to link this software with independent modules, and to copy and
14 | * distribute the resulting executable under terms of your choice, provided that
15 | * you also meet, for each linked independent module, the terms and conditions of
16 | * the license of that module. An independent module is a module which is not
17 | * derived from this software. The special exception does not apply to any
18 | * modifications of the software.
19 | *
20 | * Notwithstanding the above, under no circumstances may you combine this
21 | * software in any way with any other Broadcom software provided under a license
22 | * other than the GPL, without Broadcom's express prior written consent.
23 | *
24 | * $Id: bcm_cfg.h 351867 2012-08-21 18:46:16Z $
25 | */
26 |
27 | #ifndef _bcm_cfg_h_
28 | #define _bcm_cfg_h_
29 | #endif /* _bcm_cfg_h_ */
30 |
--------------------------------------------------------------------------------
/bcmdefs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Misc system wide definitions
3 | *
4 | * Copyright (C) 1999-2013, Broadcom Corporation
5 | *
6 | * Unless you and Broadcom execute a separate written software license
7 | * agreement governing use of this software, this software is licensed to you
8 | * under the terms of the GNU General Public License version 2 (the "GPL"),
9 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10 | * following added to such license:
11 | *
12 | * As a special exception, the copyright holders of this software give you
13 | * permission to link this software with independent modules, and to copy and
14 | * distribute the resulting executable under terms of your choice, provided that
15 | * you also meet, for each linked independent module, the terms and conditions of
16 | * the license of that module. An independent module is a module which is not
17 | * derived from this software. The special exception does not apply to any
18 | * modifications of the software.
19 | *
20 | * Notwithstanding the above, under no circumstances may you combine this
21 | * software in any way with any other Broadcom software provided under a license
22 | * other than the GPL, without Broadcom's express prior written consent.
23 | *
24 | * $Id: bcmdefs.h 416231 2013-08-02 07:38:34Z $
25 | */
26 |
27 | #ifndef _bcmdefs_h_
28 | #define _bcmdefs_h_
29 |
30 | /*
31 | * One doesn't need to include this file explicitly, gets included automatically if
32 | * typedefs.h is included.
33 | */
34 |
35 | /* Use BCM_REFERENCE to suppress warnings about intentionally-unused function
36 | * arguments or local variables.
37 | */
38 | #define BCM_REFERENCE(data) ((void)(data))
39 |
40 | /* Compile-time assert can be used in place of ASSERT if the expression evaluates
41 | * to a constant at compile time.
42 | */
43 | #define STATIC_ASSERT(expr) { \
44 | /* Make sure the expression is constant. */ \
45 | typedef enum { _STATIC_ASSERT_NOT_CONSTANT = (expr) } _static_assert_e; \
46 | /* Make sure the expression is true. */ \
47 | typedef char STATIC_ASSERT_FAIL[(expr) ? 1 : -1]; \
48 | }
49 |
50 | /* Reclaiming text and data :
51 | * The following macros specify special linker sections that can be reclaimed
52 | * after a system is considered 'up'.
53 | * BCMATTACHFN is also used for detach functions (it's not worth having a BCMDETACHFN,
54 | * as in most cases, the attach function calls the detach function to clean up on error).
55 | */
56 |
57 | #define bcmreclaimed 0
58 | #define _data _data
59 | #define _fn _fn
60 | #define BCMPREATTACHDATA(_data) _data
61 | #define BCMPREATTACHFN(_fn) _fn
62 | #define _data _data
63 | #define _fn _fn
64 | #define _fn _fn
65 | #define BCMNMIATTACHFN(_fn) _fn
66 | #define BCMNMIATTACHDATA(_data) _data
67 | #define CONST const
68 |
69 | /* Do not put BCM47XX and __ARM_ARCH_7A__ to the same line.
70 | * DHD build has problem because the BCM47XX will be excluded in DHD release.
71 | */
72 | #undef BCM47XX_CA9
73 | #ifdef __ARM_ARCH_7A__
74 | #define BCM47XX_CA9
75 | #endif /* __ARM_ARCH_7A__ */
76 | #ifndef BCMFASTPATH
77 | #if defined(BCM47XX_CA9)
78 | #define BCMFASTPATH __attribute__ ((__section__ (".text.fastpath")))
79 | #define BCMFASTPATH_HOST __attribute__ ((__section__ (".text.fastpath_host")))
80 | #else
81 | #define BCMFASTPATH
82 | #define BCMFASTPATH_HOST
83 | #endif
84 | #endif /* BCMFASTPATH */
85 |
86 |
87 | /* Put some library data/code into ROM to reduce RAM requirements */
88 | #define _data _data
89 | #define BCMROMDAT_NAME(_data) _data
90 | #define _fn _fn
91 | #define _fn _fn
92 | #define STATIC static
93 | #define BCMROMDAT_ARYSIZ(data) ARRAYSIZE(data)
94 | #define BCMROMDAT_SIZEOF(data) sizeof(data)
95 | #define BCMROMDAT_APATCH(data)
96 | #define BCMROMDAT_SPATCH(data)
97 |
98 | /* Bus types */
99 | #define SI_BUS 0 /* SOC Interconnect */
100 | #define PCI_BUS 1 /* PCI target */
101 | #define PCMCIA_BUS 2 /* PCMCIA target */
102 | #define SDIO_BUS 3 /* SDIO target */
103 | #define JTAG_BUS 4 /* JTAG */
104 | #define USB_BUS 5 /* USB (does not support R/W REG) */
105 | #define SPI_BUS 6 /* gSPI target */
106 | #define RPC_BUS 7 /* RPC target */
107 |
108 | /* Allows size optimization for single-bus image */
109 | #ifdef BCMBUSTYPE
110 | #define BUSTYPE(bus) (BCMBUSTYPE)
111 | #else
112 | #define BUSTYPE(bus) (bus)
113 | #endif
114 |
115 | /* Allows size optimization for single-backplane image */
116 | #ifdef BCMCHIPTYPE
117 | #define CHIPTYPE(bus) (BCMCHIPTYPE)
118 | #else
119 | #define CHIPTYPE(bus) (bus)
120 | #endif
121 |
122 |
123 | /* Allows size optimization for SPROM support */
124 | #if defined(BCMSPROMBUS)
125 | #define SPROMBUS (BCMSPROMBUS)
126 | #elif defined(SI_PCMCIA_SROM)
127 | #define SPROMBUS (PCMCIA_BUS)
128 | #else
129 | #define SPROMBUS (PCI_BUS)
130 | #endif
131 |
132 | /* Allows size optimization for single-chip image */
133 | #ifdef BCMCHIPID
134 | #define CHIPID(chip) (BCMCHIPID)
135 | #else
136 | #define CHIPID(chip) (chip)
137 | #endif
138 |
139 | #ifdef BCMCHIPREV
140 | #define CHIPREV(rev) (BCMCHIPREV)
141 | #else
142 | #define CHIPREV(rev) (rev)
143 | #endif
144 |
145 | /* Defines for DMA Address Width - Shared between OSL and HNDDMA */
146 | #define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */
147 | #define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */
148 | #define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */
149 |
150 | #define DMADDRWIDTH_30 30 /* 30-bit addressing capability */
151 | #define DMADDRWIDTH_32 32 /* 32-bit addressing capability */
152 | #define DMADDRWIDTH_63 63 /* 64-bit addressing capability */
153 | #define DMADDRWIDTH_64 64 /* 64-bit addressing capability */
154 |
155 | #ifdef BCMDMA64OSL
156 | typedef struct {
157 | uint32 loaddr;
158 | uint32 hiaddr;
159 | } dma64addr_t;
160 |
161 | typedef dma64addr_t dmaaddr_t;
162 | #define PHYSADDRHI(_pa) ((_pa).hiaddr)
163 | #define PHYSADDRHISET(_pa, _val) \
164 | do { \
165 | (_pa).hiaddr = (_val); \
166 | } while (0)
167 | #define PHYSADDRLO(_pa) ((_pa).loaddr)
168 | #define PHYSADDRLOSET(_pa, _val) \
169 | do { \
170 | (_pa).loaddr = (_val); \
171 | } while (0)
172 |
173 | #else
174 | typedef unsigned long dmaaddr_t;
175 | #define PHYSADDRHI(_pa) (0)
176 | #define PHYSADDRHISET(_pa, _val)
177 | #define PHYSADDRLO(_pa) ((_pa))
178 | #define PHYSADDRLOSET(_pa, _val) \
179 | do { \
180 | (_pa) = (_val); \
181 | } while (0)
182 | #endif /* BCMDMA64OSL */
183 |
184 | /* One physical DMA segment */
185 | typedef struct {
186 | dmaaddr_t addr;
187 | uint32 length;
188 | } hnddma_seg_t;
189 |
190 | #define MAX_DMA_SEGS 4
191 |
192 |
193 | typedef struct {
194 | void *oshdmah; /* Opaque handle for OSL to store its information */
195 | uint origsize; /* Size of the virtual packet */
196 | uint nsegs;
197 | hnddma_seg_t segs[MAX_DMA_SEGS];
198 | } hnddma_seg_map_t;
199 |
200 |
201 | /* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF).
202 | * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL.
203 | * There is a compile time check in wlc.c which ensure that this value is at least as big
204 | * as TXOFF. This value is used in dma_rxfill (hnddma.c).
205 | */
206 |
207 | #if defined(BCM_RPC_NOCOPY) || defined(BCM_RCP_TXNOCOPY)
208 | /* add 40 bytes to allow for extra RPC header and info */
209 | #define BCMEXTRAHDROOM 260
210 | #else /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */
211 | #if defined(BCM47XX_CA9)
212 | #define BCMEXTRAHDROOM 224
213 | #else
214 | #define BCMEXTRAHDROOM 204
215 | #endif /* linux && BCM47XX_CA9 */
216 | #endif /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */
217 |
218 | /* Packet alignment for most efficient SDIO (can change based on platform) */
219 | #ifndef SDALIGN
220 | #define SDALIGN 32
221 | #endif
222 |
223 | /* Headroom required for dongle-to-host communication. Packets allocated
224 | * locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should
225 | * leave this much room in front for low-level message headers which may
226 | * be needed to get across the dongle bus to the host. (These messages
227 | * don't go over the network, so room for the full WL header above would
228 | * be a waste.).
229 | */
230 | #define BCMDONGLEHDRSZ 12
231 | #define BCMDONGLEPADSZ 16
232 |
233 | #define BCMDONGLEOVERHEAD (BCMDONGLEHDRSZ + BCMDONGLEPADSZ)
234 |
235 |
236 | #if defined(NO_BCMDBG_ASSERT)
237 | # undef BCMDBG_ASSERT
238 | # undef BCMASSERT_LOG
239 | #endif
240 |
241 | #if defined(BCMASSERT_LOG)
242 | #define BCMASSERT_SUPPORT
243 | #endif
244 |
245 | /* Macros for doing definition and get/set of bitfields
246 | * Usage example, e.g. a three-bit field (bits 4-6):
247 | * #define _M BITFIELD_MASK(3)
248 | * #define _S 4
249 | * ...
250 | * regval = R_REG(osh, ®s->regfoo);
251 | * field = GFIELD(regval, );
252 | * regval = SFIELD(regval, , 1);
253 | * W_REG(osh, ®s->regfoo, regval);
254 | */
255 | #define BITFIELD_MASK(width) \
256 | (((unsigned)1 << (width)) - 1)
257 | #define GFIELD(val, field) \
258 | (((val) >> field ## _S) & field ## _M)
259 | #define SFIELD(val, field, bits) \
260 | (((val) & (~(field ## _M << field ## _S))) | \
261 | ((unsigned)(bits) << field ## _S))
262 |
263 | /* define BCMSMALL to remove misc features for memory-constrained environments */
264 | #ifdef BCMSMALL
265 | #undef BCMSPACE
266 | #define bcmspace FALSE /* if (bcmspace) code is discarded */
267 | #else
268 | #define BCMSPACE
269 | #define bcmspace TRUE /* if (bcmspace) code is retained */
270 | #endif
271 |
272 | /* Max. nvram variable table size */
273 | #define MAXSZ_NVRAM_VARS 4096
274 |
275 |
276 | /* Max size for reclaimable NVRAM array */
277 | #ifdef DL_NVRAM
278 | #define NVRAM_ARRAY_MAXSIZE DL_NVRAM
279 | #else
280 | #define NVRAM_ARRAY_MAXSIZE MAXSZ_NVRAM_VARS
281 | #endif /* DL_NVRAM */
282 |
283 | #ifdef BCMUSBDEV_ENABLED
284 | extern uint32 gFWID;
285 | #endif
286 |
287 | #endif /* _bcmdefs_h_ */
288 |
--------------------------------------------------------------------------------
/bcmutils.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Misc useful os-independent macros and functions.
3 | *
4 | * Copyright (C) 1999-2013, Broadcom Corporation
5 | *
6 | * Unless you and Broadcom execute a separate written software license
7 | * agreement governing use of this software, this software is licensed to you
8 | * under the terms of the GNU General Public License version 2 (the "GPL"),
9 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10 | * following added to such license:
11 | *
12 | * As a special exception, the copyright holders of this software give you
13 | * permission to link this software with independent modules, and to copy and
14 | * distribute the resulting executable under terms of your choice, provided that
15 | * you also meet, for each linked independent module, the terms and conditions of
16 | * the license of that module. An independent module is a module which is not
17 | * derived from this software. The special exception does not apply to any
18 | * modifications of the software.
19 | *
20 | * Notwithstanding the above, under no circumstances may you combine this
21 | * software in any way with any other Broadcom software provided under a license
22 | * other than the GPL, without Broadcom's express prior written consent.
23 | *
24 | * $Id: bcmutils.h 412804 2013-07-16 16:26:39Z $
25 | */
26 |
27 | #ifndef _bcmutils_h_
28 | #define _bcmutils_h_
29 |
30 | #define bcm_strcpy_s(dst, noOfElements, src) strcpy((dst), (src))
31 | #define bcm_strncpy_s(dst, noOfElements, src, count) strncpy((dst), (src), (count))
32 | #define bcm_strcat_s(dst, noOfElements, src) strcat((dst), (src))
33 |
34 | #ifdef __cplusplus
35 | extern "C" {
36 | #endif
37 |
38 | #ifdef PKTQ_LOG
39 | #include
40 | #endif
41 |
42 | /* ctype replacement */
43 | #define _BCM_U 0x01 /* upper */
44 | #define _BCM_L 0x02 /* lower */
45 | #define _BCM_D 0x04 /* digit */
46 | #define _BCM_C 0x08 /* cntrl */
47 | #define _BCM_P 0x10 /* punct */
48 | #define _BCM_S 0x20 /* white space (space/lf/tab) */
49 | #define _BCM_X 0x40 /* hex digit */
50 | #define _BCM_SP 0x80 /* hard space (0x20) */
51 |
52 | extern const unsigned char bcm_ctype[];
53 | #define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)])
54 |
55 | #define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0)
56 | #define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0)
57 | #define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0)
58 | #define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0)
59 | #define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0)
60 | #define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0)
61 | #define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0)
62 | #define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0)
63 | #define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0)
64 | #define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0)
65 | #define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0)
66 | #define bcm_tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
67 | #define bcm_toupper(c) (bcm_islower((c)) ? ((c) + 'A' - 'a') : (c))
68 |
69 | /* Buffer structure for collecting string-formatted data
70 | * using bcm_bprintf() API.
71 | * Use bcm_binit() to initialize before use
72 | */
73 |
74 | struct bcmstrbuf {
75 | char *buf; /* pointer to current position in origbuf */
76 | unsigned int size; /* current (residual) size in bytes */
77 | char *origbuf; /* unmodified pointer to orignal buffer */
78 | unsigned int origsize; /* unmodified orignal buffer size in bytes */
79 | };
80 |
81 | /* ** driver-only section ** */
82 | #ifdef BCMDRIVER
83 | #include
84 |
85 | #define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */
86 |
87 | /*
88 | * Spin at most 'us' microseconds while 'exp' is true.
89 | * Caller should explicitly test 'exp' when this completes
90 | * and take appropriate error action if 'exp' is still true.
91 | */
92 | #define SPINWAIT(exp, us) { \
93 | uint countdown = (us) + 9; \
94 | while ((exp) && (countdown >= 10)) {\
95 | OSL_DELAY(10); \
96 | countdown -= 10; \
97 | } \
98 | }
99 |
100 | /* osl multi-precedence packet queue */
101 | #ifndef PKTQ_LEN_DEFAULT
102 | #define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */
103 | #endif
104 | #ifndef PKTQ_MAX_PREC
105 | #define PKTQ_MAX_PREC 16 /* Maximum precedence levels */
106 | #endif
107 |
108 | typedef struct pktq_prec {
109 | void *head; /* first packet to dequeue */
110 | void *tail; /* last packet to dequeue */
111 | uint16 len; /* number of queued packets */
112 | uint16 max; /* maximum number of queued packets */
113 | } pktq_prec_t;
114 |
115 | #ifdef PKTQ_LOG
116 | typedef struct {
117 | uint32 requested; /* packets requested to be stored */
118 | uint32 stored; /* packets stored */
119 | uint32 saved; /* packets saved,
120 | because a lowest priority queue has given away one packet
121 | */
122 | uint32 selfsaved; /* packets saved,
123 | because an older packet from the same queue has been dropped
124 | */
125 | uint32 full_dropped; /* packets dropped,
126 | because pktq is full with higher precedence packets
127 | */
128 | uint32 dropped; /* packets dropped because pktq per that precedence is full */
129 | uint32 sacrificed; /* packets dropped,
130 | in order to save one from a queue of a highest priority
131 | */
132 | uint32 busy; /* packets droped because of hardware/transmission error */
133 | uint32 retry; /* packets re-sent because they were not received */
134 | uint32 ps_retry; /* packets retried again prior to moving power save mode */
135 | uint32 retry_drop; /* packets finally dropped after retry limit */
136 | uint32 max_avail; /* the high-water mark of the queue capacity for packets -
137 | goes to zero as queue fills
138 | */
139 | uint32 max_used; /* the high-water mark of the queue utilisation for packets -
140 | increases with use ('inverse' of max_avail)
141 | */
142 | uint32 queue_capacity; /* the maximum capacity of the queue */
143 | uint32 rtsfail; /* count of rts attempts that failed to receive cts */
144 | uint32 acked; /* count of packets sent (acked) successfully */
145 | } pktq_counters_t;
146 | #endif /* PKTQ_LOG */
147 |
148 |
149 | #define PKTQ_COMMON \
150 | uint16 num_prec; /* number of precedences in use */ \
151 | uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ \
152 | uint16 max; /* total max packets */ \
153 | uint16 len; /* total number of packets */
154 |
155 | /* multi-priority pkt queue */
156 | struct pktq {
157 | PKTQ_COMMON
158 | /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */
159 | struct pktq_prec q[PKTQ_MAX_PREC];
160 | #ifdef PKTQ_LOG
161 | pktq_counters_t _prec_cnt[PKTQ_MAX_PREC]; /* Counters per queue */
162 | pktq_counters_t _prec_bytes[PKTQ_MAX_PREC]; /* Byte count per queue */
163 | uint32 _logtime; /* timestamp of last counter clear */
164 | #endif
165 | };
166 |
167 | /* simple, non-priority pkt queue */
168 | struct spktq {
169 | PKTQ_COMMON
170 | /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */
171 | struct pktq_prec q[1];
172 | };
173 |
174 | #define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--)
175 |
176 | /* fn(pkt, arg). return true if pkt belongs to if */
177 | typedef bool (*ifpkt_cb_t)(void*, int);
178 |
179 | #ifdef BCMPKTPOOL
180 | #define POOL_ENAB(pool) ((pool) && (pool)->inited)
181 | #define SHARED_POOL (pktpool_shared)
182 | #else /* BCMPKTPOOL */
183 | #define POOL_ENAB(bus) 0
184 | #define SHARED_POOL ((struct pktpool *)NULL)
185 | #endif /* BCMPKTPOOL */
186 |
187 | #ifndef PKTPOOL_LEN_MAX
188 | #define PKTPOOL_LEN_MAX 40
189 | #endif /* PKTPOOL_LEN_MAX */
190 | #define PKTPOOL_CB_MAX 3
191 |
192 | struct pktpool;
193 | typedef void (*pktpool_cb_t)(struct pktpool *pool, void *arg);
194 | typedef struct {
195 | pktpool_cb_t cb;
196 | void *arg;
197 | } pktpool_cbinfo_t;
198 |
199 | #ifdef BCMDBG_POOL
200 | /* pkt pool debug states */
201 | #define POOL_IDLE 0
202 | #define POOL_RXFILL 1
203 | #define POOL_RXDH 2
204 | #define POOL_RXD11 3
205 | #define POOL_TXDH 4
206 | #define POOL_TXD11 5
207 | #define POOL_AMPDU 6
208 | #define POOL_TXENQ 7
209 |
210 | typedef struct {
211 | void *p;
212 | uint32 cycles;
213 | uint32 dur;
214 | } pktpool_dbg_t;
215 |
216 | typedef struct {
217 | uint8 txdh; /* tx to host */
218 | uint8 txd11; /* tx to d11 */
219 | uint8 enq; /* waiting in q */
220 | uint8 rxdh; /* rx from host */
221 | uint8 rxd11; /* rx from d11 */
222 | uint8 rxfill; /* dma_rxfill */
223 | uint8 idle; /* avail in pool */
224 | } pktpool_stats_t;
225 | #endif /* BCMDBG_POOL */
226 |
227 | typedef struct pktpool {
228 | bool inited;
229 | uint16 r;
230 | uint16 w;
231 | uint16 len;
232 | uint16 maxlen;
233 | uint16 plen;
234 | bool istx;
235 | bool empty;
236 | uint8 cbtoggle;
237 | uint8 cbcnt;
238 | uint8 ecbcnt;
239 | bool emptycb_disable;
240 | pktpool_cbinfo_t *availcb_excl;
241 | pktpool_cbinfo_t cbs[PKTPOOL_CB_MAX];
242 | pktpool_cbinfo_t ecbs[PKTPOOL_CB_MAX];
243 | void *q[PKTPOOL_LEN_MAX + 1];
244 |
245 | #ifdef BCMDBG_POOL
246 | uint8 dbg_cbcnt;
247 | pktpool_cbinfo_t dbg_cbs[PKTPOOL_CB_MAX];
248 | uint16 dbg_qlen;
249 | pktpool_dbg_t dbg_q[PKTPOOL_LEN_MAX + 1];
250 | #endif
251 | } pktpool_t;
252 |
253 | extern pktpool_t *pktpool_shared;
254 |
255 | extern int pktpool_init(osl_t *osh, pktpool_t *pktp, int *pktplen, int plen, bool istx);
256 | extern int pktpool_deinit(osl_t *osh, pktpool_t *pktp);
257 | extern int pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal);
258 | extern void* pktpool_get(pktpool_t *pktp);
259 | extern void pktpool_free(pktpool_t *pktp, void *p);
260 | extern int pktpool_add(pktpool_t *pktp, void *p);
261 | extern uint16 pktpool_avail(pktpool_t *pktp);
262 | extern int pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp);
263 | extern int pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, pktpool_cb_t cb);
264 | extern int pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
265 | extern int pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
266 | extern int pktpool_setmaxlen(pktpool_t *pktp, uint16 maxlen);
267 | extern int pktpool_setmaxlen_strict(osl_t *osh, pktpool_t *pktp, uint16 maxlen);
268 | extern void pktpool_emptycb_disable(pktpool_t *pktp, bool disable);
269 | extern bool pktpool_emptycb_disabled(pktpool_t *pktp);
270 |
271 | #define POOLPTR(pp) ((pktpool_t *)(pp))
272 | #define pktpool_len(pp) (POOLPTR(pp)->len - 1)
273 | #define pktpool_plen(pp) (POOLPTR(pp)->plen)
274 | #define pktpool_maxlen(pp) (POOLPTR(pp)->maxlen)
275 |
276 | #ifdef BCMDBG_POOL
277 | extern int pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
278 | extern int pktpool_start_trigger(pktpool_t *pktp, void *p);
279 | extern int pktpool_dbg_dump(pktpool_t *pktp);
280 | extern int pktpool_dbg_notify(pktpool_t *pktp);
281 | extern int pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats);
282 | #endif /* BCMDBG_POOL */
283 |
284 | /* forward definition of ether_addr structure used by some function prototypes */
285 |
286 | struct ether_addr;
287 |
288 | extern int ether_isbcast(const void *ea);
289 | extern int ether_isnulladdr(const void *ea);
290 |
291 | /* operations on a specific precedence in packet queue */
292 |
293 | #define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max))
294 | #define pktq_pmax(pq, prec) ((pq)->q[prec].max)
295 | #define pktq_plen(pq, prec) ((pq)->q[prec].len)
296 | #define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len)
297 | #define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max)
298 | #define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0)
299 |
300 | #define pktq_ppeek(pq, prec) ((pq)->q[prec].head)
301 | #define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail)
302 |
303 | extern void *pktq_penq(struct pktq *pq, int prec, void *p);
304 | extern void *pktq_penq_head(struct pktq *pq, int prec, void *p);
305 | extern void *pktq_pdeq(struct pktq *pq, int prec);
306 | extern void *pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p);
307 | extern void *pktq_pdeq_with_fn(struct pktq *pq, int prec, ifpkt_cb_t fn, int arg);
308 | extern void *pktq_pdeq_tail(struct pktq *pq, int prec);
309 | /* Empty the queue at particular precedence level */
310 | extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir,
311 | ifpkt_cb_t fn, int arg);
312 | /* Remove a specified packet from its queue */
313 | extern bool pktq_pdel(struct pktq *pq, void *p, int prec);
314 |
315 | /* operations on a set of precedences in packet queue */
316 |
317 | extern int pktq_mlen(struct pktq *pq, uint prec_bmp);
318 | extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out);
319 | extern void *pktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out);
320 |
321 | /* operations on packet queue as a whole */
322 |
323 | #define pktq_len(pq) ((int)(pq)->len)
324 | #define pktq_max(pq) ((int)(pq)->max)
325 | #define pktq_avail(pq) ((int)((pq)->max - (pq)->len))
326 | #define pktq_full(pq) ((pq)->len >= (pq)->max)
327 | #define pktq_empty(pq) ((pq)->len == 0)
328 |
329 | /* operations for single precedence queues */
330 | #define pktenq(pq, p) pktq_penq(((struct pktq *)(void *)pq), 0, (p))
331 | #define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)(void *)pq), 0, (p))
332 | #define pktdeq(pq) pktq_pdeq(((struct pktq *)(void *)pq), 0)
333 | #define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)(void *)pq), 0)
334 | #define pktqinit(pq, len) pktq_init(((struct pktq *)(void *)pq), 1, len)
335 |
336 | extern void pktq_init(struct pktq *pq, int num_prec, int max_len);
337 | extern void pktq_set_max_plen(struct pktq *pq, int prec, int max_len);
338 |
339 | /* prec_out may be NULL if caller is not interested in return value */
340 | extern void *pktq_deq(struct pktq *pq, int *prec_out);
341 | extern void *pktq_deq_tail(struct pktq *pq, int *prec_out);
342 | extern void *pktq_peek(struct pktq *pq, int *prec_out);
343 | extern void *pktq_peek_tail(struct pktq *pq, int *prec_out);
344 | extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg);
345 |
346 | /* externs */
347 | /* packet */
348 | extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf);
349 | extern uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf);
350 | extern uint pkttotlen(osl_t *osh, void *p);
351 | extern void *pktlast(osl_t *osh, void *p);
352 | extern uint pktsegcnt(osl_t *osh, void *p);
353 | extern uint pktsegcnt_war(osl_t *osh, void *p);
354 | extern uint8 *pktdataoffset(osl_t *osh, void *p, uint offset);
355 | extern void *pktoffset(osl_t *osh, void *p, uint offset);
356 |
357 | /* Get priority from a packet and pass it back in scb (or equiv) */
358 | #define PKTPRIO_VDSCP 0x100 /* DSCP prio found after VLAN tag */
359 | #define PKTPRIO_VLAN 0x200 /* VLAN prio found */
360 | #define PKTPRIO_UPD 0x400 /* DSCP used to update VLAN prio */
361 | #define PKTPRIO_DSCP 0x800 /* DSCP prio found */
362 |
363 | /* DSCP type definitions (RFC4594) */
364 | /* AF1x: High-Throughput Data (RFC2597) */
365 | #define DSCP_AF11 0x0A
366 | #define DSCP_AF12 0x0C
367 | #define DSCP_AF13 0x0E
368 | /* AF2x: Low-Latency Data (RFC2597) */
369 | #define DSCP_AF21 0x12
370 | #define DSCP_AF22 0x14
371 | #define DSCP_AF23 0x16
372 | /* AF3x: Multimedia Streaming (RFC2597) */
373 | #define DSCP_AF31 0x1A
374 | #define DSCP_AF32 0x1C
375 | #define DSCP_AF33 0x1E
376 | /* EF: Telephony (RFC3246) */
377 | #define DSCP_EF 0x2E
378 |
379 | extern uint pktsetprio(void *pkt, bool update_vtag);
380 |
381 | /* string */
382 | extern int bcm_atoi(const char *s);
383 | extern ulong bcm_strtoul(const char *cp, char **endp, uint base);
384 | extern char *bcmstrstr(const char *haystack, const char *needle);
385 | extern char *bcmstrcat(char *dest, const char *src);
386 | extern char *bcmstrncat(char *dest, const char *src, uint size);
387 | extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen);
388 | char* bcmstrtok(char **string, const char *delimiters, char *tokdelim);
389 | int bcmstricmp(const char *s1, const char *s2);
390 | int bcmstrnicmp(const char* s1, const char* s2, int cnt);
391 |
392 |
393 | /* ethernet address */
394 | extern char *bcm_ether_ntoa(const struct ether_addr *ea, char *buf);
395 | extern int bcm_ether_atoe(const char *p, struct ether_addr *ea);
396 |
397 | /* ip address */
398 | struct ipv4_addr;
399 | extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf);
400 |
401 | /* delay */
402 | extern void bcm_mdelay(uint ms);
403 | /* variable access */
404 | #define NVRAM_RECLAIM_CHECK(name)
405 |
406 | extern char *getvar(char *vars, const char *name);
407 | extern int getintvar(char *vars, const char *name);
408 | extern int getintvararray(char *vars, const char *name, int index);
409 | extern int getintvararraysize(char *vars, const char *name);
410 | extern uint getgpiopin(char *vars, char *pin_name, uint def_pin);
411 | #define bcm_perf_enable()
412 | #define bcmstats(fmt)
413 | #define bcmlog(fmt, a1, a2)
414 | #define bcmdumplog(buf, size) *buf = '\0'
415 | #define bcmdumplogent(buf, idx) -1
416 |
417 | #define bcmtslog(tstamp, fmt, a1, a2)
418 | #define bcmprinttslogs()
419 | #define bcmprinttstamp(us)
420 | #define bcmdumptslog(buf, size)
421 |
422 | extern char *bcm_nvram_vars(uint *length);
423 | extern int bcm_nvram_cache(void *sih);
424 |
425 | /* Support for sharing code across in-driver iovar implementations.
426 | * The intent is that a driver use this structure to map iovar names
427 | * to its (private) iovar identifiers, and the lookup function to
428 | * find the entry. Macros are provided to map ids and get/set actions
429 | * into a single number space for a switch statement.
430 | */
431 |
432 | /* iovar structure */
433 | typedef struct bcm_iovar {
434 | const char *name; /* name for lookup and display */
435 | uint16 varid; /* id for switch */
436 | uint16 flags; /* driver-specific flag bits */
437 | uint16 type; /* base type of argument */
438 | uint16 minlen; /* min length for buffer vars */
439 | } bcm_iovar_t;
440 |
441 | /* varid definitions are per-driver, may use these get/set bits */
442 |
443 | /* IOVar action bits for id mapping */
444 | #define IOV_GET 0 /* Get an iovar */
445 | #define IOV_SET 1 /* Set an iovar */
446 |
447 | /* Varid to actionid mapping */
448 | #define IOV_GVAL(id) ((id) * 2)
449 | #define IOV_SVAL(id) ((id) * 2 + IOV_SET)
450 | #define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET)
451 | #define IOV_ID(actionid) (actionid >> 1)
452 |
453 | /* flags are per-driver based on driver attributes */
454 |
455 | extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name);
456 | extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set);
457 | #if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \
458 | defined(WLMSG_PRPKT) || defined(WLMSG_WSEC)
459 | extern int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len);
460 | #endif
461 | #endif /* BCMDRIVER */
462 |
463 | /* Base type definitions */
464 | #define IOVT_VOID 0 /* no value (implictly set only) */
465 | #define IOVT_BOOL 1 /* any value ok (zero/nonzero) */
466 | #define IOVT_INT8 2 /* integer values are range-checked */
467 | #define IOVT_UINT8 3 /* unsigned int 8 bits */
468 | #define IOVT_INT16 4 /* int 16 bits */
469 | #define IOVT_UINT16 5 /* unsigned int 16 bits */
470 | #define IOVT_INT32 6 /* int 32 bits */
471 | #define IOVT_UINT32 7 /* unsigned int 32 bits */
472 | #define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */
473 | #define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER)
474 |
475 | /* Initializer for IOV type strings */
476 | #define BCM_IOV_TYPE_INIT { \
477 | "void", \
478 | "bool", \
479 | "int8", \
480 | "uint8", \
481 | "int16", \
482 | "uint16", \
483 | "int32", \
484 | "uint32", \
485 | "buffer", \
486 | "" }
487 |
488 | #define BCM_IOVT_IS_INT(type) (\
489 | (type == IOVT_BOOL) || \
490 | (type == IOVT_INT8) || \
491 | (type == IOVT_UINT8) || \
492 | (type == IOVT_INT16) || \
493 | (type == IOVT_UINT16) || \
494 | (type == IOVT_INT32) || \
495 | (type == IOVT_UINT32))
496 |
497 | /* ** driver/apps-shared section ** */
498 |
499 | #define BCME_STRLEN 64 /* Max string length for BCM errors */
500 | #define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST))
501 |
502 |
503 | /*
504 | * error codes could be added but the defined ones shouldn't be changed/deleted
505 | * these error codes are exposed to the user code
506 | * when ever a new error code is added to this list
507 | * please update errorstring table with the related error string and
508 | * update osl files with os specific errorcode map
509 | */
510 |
511 | #define BCME_OK 0 /* Success */
512 | #define BCME_ERROR -1 /* Error generic */
513 | #define BCME_BADARG -2 /* Bad Argument */
514 | #define BCME_BADOPTION -3 /* Bad option */
515 | #define BCME_NOTUP -4 /* Not up */
516 | #define BCME_NOTDOWN -5 /* Not down */
517 | #define BCME_NOTAP -6 /* Not AP */
518 | #define BCME_NOTSTA -7 /* Not STA */
519 | #define BCME_BADKEYIDX -8 /* BAD Key Index */
520 | #define BCME_RADIOOFF -9 /* Radio Off */
521 | #define BCME_NOTBANDLOCKED -10 /* Not band locked */
522 | #define BCME_NOCLK -11 /* No Clock */
523 | #define BCME_BADRATESET -12 /* BAD Rate valueset */
524 | #define BCME_BADBAND -13 /* BAD Band */
525 | #define BCME_BUFTOOSHORT -14 /* Buffer too short */
526 | #define BCME_BUFTOOLONG -15 /* Buffer too long */
527 | #define BCME_BUSY -16 /* Busy */
528 | #define BCME_NOTASSOCIATED -17 /* Not Associated */
529 | #define BCME_BADSSIDLEN -18 /* Bad SSID len */
530 | #define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */
531 | #define BCME_BADCHAN -20 /* Bad Channel */
532 | #define BCME_BADADDR -21 /* Bad Address */
533 | #define BCME_NORESOURCE -22 /* Not Enough Resources */
534 | #define BCME_UNSUPPORTED -23 /* Unsupported */
535 | #define BCME_BADLEN -24 /* Bad length */
536 | #define BCME_NOTREADY -25 /* Not Ready */
537 | #define BCME_EPERM -26 /* Not Permitted */
538 | #define BCME_NOMEM -27 /* No Memory */
539 | #define BCME_ASSOCIATED -28 /* Associated */
540 | #define BCME_RANGE -29 /* Not In Range */
541 | #define BCME_NOTFOUND -30 /* Not Found */
542 | #define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */
543 | #define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */
544 | #define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */
545 | #define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */
546 | #define BCME_SDIO_ERROR -35 /* SDIO Bus Error */
547 | #define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */
548 | #define BCME_VERSION -37 /* Incorrect version */
549 | #define BCME_TXFAIL -38 /* TX failure */
550 | #define BCME_RXFAIL -39 /* RX failure */
551 | #define BCME_NODEVICE -40 /* Device not present */
552 | #define BCME_NMODE_DISABLED -41 /* NMODE disabled */
553 | #define BCME_NONRESIDENT -42 /* access to nonresident overlay */
554 | #define BCME_SCANREJECT -43 /* reject scan request */
555 | #define BCME_USAGE_ERROR -44 /* WLCMD usage error */
556 | #define BCME_IOCTL_ERROR -45 /* WLCMD ioctl error */
557 | #define BCME_SERIAL_PORT_ERR -46 /* RWL serial port error */
558 | #define BCME_LAST BCME_SERIAL_PORT_ERR
559 |
560 | /* These are collection of BCME Error strings */
561 | #define BCMERRSTRINGTABLE { \
562 | "OK", \
563 | "Undefined error", \
564 | "Bad Argument", \
565 | "Bad Option", \
566 | "Not up", \
567 | "Not down", \
568 | "Not AP", \
569 | "Not STA", \
570 | "Bad Key Index", \
571 | "Radio Off", \
572 | "Not band locked", \
573 | "No clock", \
574 | "Bad Rate valueset", \
575 | "Bad Band", \
576 | "Buffer too short", \
577 | "Buffer too long", \
578 | "Busy", \
579 | "Not Associated", \
580 | "Bad SSID len", \
581 | "Out of Range Channel", \
582 | "Bad Channel", \
583 | "Bad Address", \
584 | "Not Enough Resources", \
585 | "Unsupported", \
586 | "Bad length", \
587 | "Not Ready", \
588 | "Not Permitted", \
589 | "No Memory", \
590 | "Associated", \
591 | "Not In Range", \
592 | "Not Found", \
593 | "WME Not Enabled", \
594 | "TSPEC Not Found", \
595 | "ACM Not Supported", \
596 | "Not WME Association", \
597 | "SDIO Bus Error", \
598 | "Dongle Not Accessible", \
599 | "Incorrect version", \
600 | "TX Failure", \
601 | "RX Failure", \
602 | "Device Not Present", \
603 | "NMODE Disabled", \
604 | "Nonresident overlay access", \
605 | "Scan Rejected", \
606 | "WLCMD usage error", \
607 | "WLCMD ioctl error", \
608 | "RWL serial port error", \
609 | }
610 |
611 | #ifndef ABS
612 | #define ABS(a) (((a) < 0) ? -(a) : (a))
613 | #endif /* ABS */
614 |
615 | #ifndef MIN
616 | #define MIN(a, b) (((a) < (b)) ? (a) : (b))
617 | #endif /* MIN */
618 |
619 | #ifndef MAX
620 | #define MAX(a, b) (((a) > (b)) ? (a) : (b))
621 | #endif /* MAX */
622 |
623 | /* limit to [min, max] */
624 | #ifndef LIMIT_TO_RANGE
625 | #define LIMIT_TO_RANGE(x, min, max) \
626 | ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
627 | #endif /* LIMIT_TO_RANGE */
628 |
629 | /* limit to max */
630 | #ifndef LIMIT_TO_MAX
631 | #define LIMIT_TO_MAX(x, max) \
632 | (((x) > (max) ? (max) : (x)))
633 | #endif /* LIMIT_TO_MAX */
634 |
635 | /* limit to min */
636 | #ifndef LIMIT_TO_MIN
637 | #define LIMIT_TO_MIN(x, min) \
638 | (((x) < (min) ? (min) : (x)))
639 | #endif /* LIMIT_TO_MIN */
640 |
641 | #define CEIL(x, y) (((x) + ((y) - 1)) / (y))
642 | #define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
643 | #define ISALIGNED(a, x) (((uintptr)(a) & ((x) - 1)) == 0)
644 | #define ALIGN_ADDR(addr, boundary) (void *)(((uintptr)(addr) + (boundary) - 1) \
645 | & ~((boundary) - 1))
646 | #define ALIGN_SIZE(size, boundary) (((size) + (boundary) - 1) \
647 | & ~((boundary) - 1))
648 | #define ISPOWEROF2(x) ((((x) - 1) & (x)) == 0)
649 | #define VALID_MASK(mask) !((mask) & ((mask) + 1))
650 |
651 | #ifndef OFFSETOF
652 | #ifdef __ARMCC_VERSION
653 | /*
654 | * The ARM RVCT compiler complains when using OFFSETOF where a constant
655 | * expression is expected, such as an initializer for a static object.
656 | * offsetof from the runtime library doesn't have that problem.
657 | */
658 | #include
659 | #define OFFSETOF(type, member) offsetof(type, member)
660 | #else
661 | #define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member)
662 | #endif /* __ARMCC_VERSION */
663 | #endif /* OFFSETOF */
664 |
665 | #ifndef ARRAYSIZE
666 | #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
667 | #endif
668 |
669 | #ifndef ARRAYLAST /* returns pointer to last array element */
670 | #define ARRAYLAST(a) (&a[ARRAYSIZE(a)-1])
671 | #endif
672 |
673 | /* Reference a function; used to prevent a static function from being optimized out */
674 | extern void *_bcmutils_dummy_fn;
675 | #define REFERENCE_FUNCTION(f) (_bcmutils_dummy_fn = (void *)(f))
676 |
677 | /* bit map related macros */
678 | #ifndef setbit
679 | #ifndef NBBY /* the BSD family defines NBBY */
680 | #define NBBY 8 /* 8 bits per byte */
681 | #endif /* #ifndef NBBY */
682 | #ifdef BCMUTILS_BIT_MACROS_USE_FUNCS
683 | extern void setbit(void *array, uint bit);
684 | extern void clrbit(void *array, uint bit);
685 | extern bool isset(const void *array, uint bit);
686 | extern bool isclr(const void *array, uint bit);
687 | #else
688 | #define setbit(a, i) (((uint8 *)a)[(i) / NBBY] |= 1 << ((i) % NBBY))
689 | #define clrbit(a, i) (((uint8 *)a)[(i) / NBBY] &= ~(1 << ((i) % NBBY)))
690 | #define isset(a, i) (((const uint8 *)a)[(i) / NBBY] & (1 << ((i) % NBBY)))
691 | #define isclr(a, i) ((((const uint8 *)a)[(i) / NBBY] & (1 << ((i) % NBBY))) == 0)
692 | #endif
693 | #endif /* setbit */
694 |
695 | #define isbitset(a, i) (((a) & (1 << (i))) != 0)
696 |
697 | #define NBITS(type) (sizeof(type) * 8)
698 | #define NBITVAL(nbits) (1 << (nbits))
699 | #define MAXBITVAL(nbits) ((1 << (nbits)) - 1)
700 | #define NBITMASK(nbits) MAXBITVAL(nbits)
701 | #define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8)
702 |
703 | /* basic mux operation - can be optimized on several architectures */
704 | #define MUX(pred, true, false) ((pred) ? (true) : (false))
705 |
706 | /* modulo inc/dec - assumes x E [0, bound - 1] */
707 | #define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1)
708 | #define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
709 |
710 | /* modulo inc/dec, bound = 2^k */
711 | #define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
712 | #define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
713 |
714 | /* modulo add/sub - assumes x, y E [0, bound - 1] */
715 | #define MODADD(x, y, bound) \
716 | MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y))
717 | #define MODSUB(x, y, bound) \
718 | MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y))
719 |
720 | /* module add/sub, bound = 2^k */
721 | #define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
722 | #define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
723 |
724 | /* crc defines */
725 | #define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */
726 | #define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */
727 | #define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */
728 | #define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */
729 | #define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */
730 | #define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */
731 |
732 | /* use for direct output of MAC address in printf etc */
733 | #define MACF "%02x:%02x:%02x:%02x:%02x:%02x"
734 | #define ETHERP_TO_MACF(ea) ((struct ether_addr *) (ea))->octet[0], \
735 | ((struct ether_addr *) (ea))->octet[1], \
736 | ((struct ether_addr *) (ea))->octet[2], \
737 | ((struct ether_addr *) (ea))->octet[3], \
738 | ((struct ether_addr *) (ea))->octet[4], \
739 | ((struct ether_addr *) (ea))->octet[5]
740 |
741 | #define ETHER_TO_MACF(ea) (ea).octet[0], \
742 | (ea).octet[1], \
743 | (ea).octet[2], \
744 | (ea).octet[3], \
745 | (ea).octet[4], \
746 | (ea).octet[5]
747 | #if !defined(SIMPLE_MAC_PRINT)
748 | #define MACDBG "%02x:%02x:%02x:%02x:%02x:%02x"
749 | #define MAC2STRDBG(ea) (ea)[0], (ea)[1], (ea)[2], (ea)[3], (ea)[4], (ea)[5]
750 | #else
751 | #define MACDBG "%02x:%02x:%02x"
752 | #define MAC2STRDBG(ea) (ea)[0], (ea)[4], (ea)[5]
753 | #endif /* SIMPLE_MAC_PRINT */
754 |
755 | /* bcm_format_flags() bit description structure */
756 | typedef struct bcm_bit_desc {
757 | uint32 bit;
758 | const char* name;
759 | } bcm_bit_desc_t;
760 |
761 | /* bcm_format_field */
762 | typedef struct bcm_bit_desc_ex {
763 | uint32 mask;
764 | const bcm_bit_desc_t *bitfield;
765 | } bcm_bit_desc_ex_t;
766 |
767 |
768 | /* tag_ID/length/value_buffer tuple */
769 | typedef struct bcm_tlv {
770 | uint8 id;
771 | uint8 len;
772 | uint8 data[1];
773 | } bcm_tlv_t;
774 |
775 | /* Check that bcm_tlv_t fits into the given buflen */
776 | #define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len))
777 |
778 | /* buffer length for ethernet address from bcm_ether_ntoa() */
779 | #define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */
780 |
781 | /* crypto utility function */
782 | /* 128-bit xor: *dst = *src1 xor *src2. dst1, src1 and src2 may have any alignment */
783 | static INLINE void
784 | xor_128bit_block(const uint8 *src1, const uint8 *src2, uint8 *dst)
785 | {
786 | if (
787 | #ifdef __i386__
788 | 1 ||
789 | #endif
790 | (((uintptr)src1 | (uintptr)src2 | (uintptr)dst) & 3) == 0) {
791 | /* ARM CM3 rel time: 1229 (727 if alignment check could be omitted) */
792 | /* x86 supports unaligned. This version runs 6x-9x faster on x86. */
793 | ((uint32 *)dst)[0] = ((const uint32 *)src1)[0] ^ ((const uint32 *)src2)[0];
794 | ((uint32 *)dst)[1] = ((const uint32 *)src1)[1] ^ ((const uint32 *)src2)[1];
795 | ((uint32 *)dst)[2] = ((const uint32 *)src1)[2] ^ ((const uint32 *)src2)[2];
796 | ((uint32 *)dst)[3] = ((const uint32 *)src1)[3] ^ ((const uint32 *)src2)[3];
797 | } else {
798 | /* ARM CM3 rel time: 4668 (4191 if alignment check could be omitted) */
799 | int k;
800 | for (k = 0; k < 16; k++)
801 | dst[k] = src1[k] ^ src2[k];
802 | }
803 | }
804 |
805 | /* externs */
806 | /* crc */
807 | extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc);
808 | extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc);
809 | extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc);
810 |
811 | /* format/print */
812 | #if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \
813 | defined(WLMSG_ASSOC)
814 | /* print out the value a field has: fields may have 1-32 bits and may hold any value */
815 | extern int bcm_format_field(const bcm_bit_desc_ex_t *bd, uint32 field, char* buf, int len);
816 | /* print out which bits in flags are set */
817 | extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len);
818 | #endif
819 |
820 | #if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \
821 | defined(WLMSG_ASSOC) || defined(WLMEDIA_PEAKRATE)
822 | extern int bcm_format_hex(char *str, const void *bytes, int len);
823 | #endif
824 |
825 | extern const char *bcm_crypto_algo_name(uint algo);
826 | extern char *bcm_chipname(uint chipid, char *buf, uint len);
827 | extern char *bcm_brev_str(uint32 brev, char *buf);
828 | extern void printbig(char *buf);
829 | extern void prhex(const char *msg, uchar *buf, uint len);
830 |
831 | /* IE parsing */
832 | extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen);
833 | extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key);
834 | extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key);
835 |
836 | /* bcmerror */
837 | extern const char *bcmerrorstr(int bcmerror);
838 | /* extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); */
839 |
840 | /* multi-bool data type: set of bools, mbool is true if any is set */
841 | typedef uint32 mbool;
842 | #define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */
843 | #define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */
844 | #define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* TRUE if one bool is set */
845 | #define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val)))
846 |
847 | /* generic datastruct to help dump routines */
848 | struct fielddesc {
849 | const char *nameandfmt;
850 | uint32 offset;
851 | uint32 len;
852 | };
853 |
854 | extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size);
855 | extern void bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len);
856 |
857 | extern void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount);
858 | extern int bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes);
859 | extern void bcm_print_bytes(const char *name, const uchar *cdata, int len);
860 |
861 | typedef uint32 (*bcmutl_rdreg_rtn)(void *arg0, uint arg1, uint32 offset);
862 | extern uint bcmdumpfields(bcmutl_rdreg_rtn func_ptr, void *arg0, uint arg1, struct fielddesc *str,
863 | char *buf, uint32 bufsize);
864 | extern uint bcm_bitcount(uint8 *bitmap, uint bytelength);
865 |
866 | extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...);
867 |
868 | /* power conversion */
869 | extern uint16 bcm_qdbm_to_mw(uint8 qdbm);
870 | extern uint8 bcm_mw_to_qdbm(uint16 mw);
871 | extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len);
872 |
873 | unsigned int process_nvram_vars(char *varbuf, unsigned int len);
874 | extern bcm_tlv_t *find_vendor_ie(void *tlvs, int tlvs_len,
875 | const char *voui, uint8 *type, int type_len);
876 |
877 | /* calculate a * b + c */
878 | extern void bcm_uint64_multiple_add(uint32* r_high, uint32* r_low, uint32 a, uint32 b, uint32 c);
879 | /* calculate a / b */
880 | extern void bcm_uint64_divide(uint32* r, uint32 a_high, uint32 a_low, uint32 b);
881 |
882 | #ifdef __cplusplus
883 | }
884 | #endif
885 |
886 | #endif /* _bcmutils_h_ */
887 |
--------------------------------------------------------------------------------
/bcmwifi_channels.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Misc utility routines for WL and Apps
3 | * This header file housing the define and function prototype use by
4 | * both the wl driver, tools & Apps.
5 | *
6 | * Copyright (C) 1999-2013, Broadcom Corporation
7 | *
8 | * Unless you and Broadcom execute a separate written software license
9 | * agreement governing use of this software, this software is licensed to you
10 | * under the terms of the GNU General Public License version 2 (the "GPL"),
11 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the
12 | * following added to such license:
13 | *
14 | * As a special exception, the copyright holders of this software give you
15 | * permission to link this software with independent modules, and to copy and
16 | * distribute the resulting executable under terms of your choice, provided that
17 | * you also meet, for each linked independent module, the terms and conditions of
18 | * the license of that module. An independent module is a module which is not
19 | * derived from this software. The special exception does not apply to any
20 | * modifications of the software.
21 | *
22 | * Notwithstanding the above, under no circumstances may you combine this
23 | * software in any way with any other Broadcom software provided under a license
24 | * other than the GPL, without Broadcom's express prior written consent.
25 | *
26 | * $Id: bcmwifi_channels.h 309193 2012-01-19 00:03:57Z $
27 | */
28 |
29 | #ifndef _bcmwifi_channels_h_
30 | #define _bcmwifi_channels_h_
31 |
32 |
33 | /* A chanspec holds the channel number, band, bandwidth and control sideband */
34 | typedef uint16 chanspec_t;
35 |
36 | /* channel defines */
37 | #define CH_UPPER_SB 0x01
38 | #define CH_LOWER_SB 0x02
39 | #define CH_EWA_VALID 0x04
40 | #define CH_80MHZ_APART 16
41 | #define CH_40MHZ_APART 8
42 | #define CH_20MHZ_APART 4
43 | #define CH_10MHZ_APART 2
44 | #define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
45 | #define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
46 | #define MAXCHANNEL 224 /* max # supported channels. The max channel no is 216,
47 | * this is that + 1 rounded up to a multiple of NBBY (8).
48 | * DO NOT MAKE it > 255: channels are uint8's all over
49 | */
50 | #define CHSPEC_CTLOVLP(sp1, sp2, sep) (ABS(wf_chspec_ctlchan(sp1) - wf_chspec_ctlchan(sp2)) < \
51 | (sep))
52 |
53 | /* All builds use the new 11ac ratespec/chanspec */
54 | #undef D11AC_IOTYPES
55 | #define D11AC_IOTYPES
56 |
57 | #ifndef D11AC_IOTYPES
58 |
59 | #define WL_CHANSPEC_CHAN_MASK 0x00ff
60 | #define WL_CHANSPEC_CHAN_SHIFT 0
61 |
62 | #define WL_CHANSPEC_CTL_SB_MASK 0x0300
63 | #define WL_CHANSPEC_CTL_SB_SHIFT 8
64 | #define WL_CHANSPEC_CTL_SB_LOWER 0x0100
65 | #define WL_CHANSPEC_CTL_SB_UPPER 0x0200
66 | #define WL_CHANSPEC_CTL_SB_NONE 0x0300
67 |
68 | #define WL_CHANSPEC_BW_MASK 0x0C00
69 | #define WL_CHANSPEC_BW_SHIFT 10
70 | #define WL_CHANSPEC_BW_10 0x0400
71 | #define WL_CHANSPEC_BW_20 0x0800
72 | #define WL_CHANSPEC_BW_40 0x0C00
73 |
74 | #define WL_CHANSPEC_BAND_MASK 0xf000
75 | #define WL_CHANSPEC_BAND_SHIFT 12
76 | #ifdef WL_CHANSPEC_BAND_5G
77 | #undef WL_CHANSPEC_BAND_5G
78 | #endif
79 | #ifdef WL_CHANSPEC_BAND_2G
80 | #undef WL_CHANSPEC_BAND_2G
81 | #endif
82 | #define WL_CHANSPEC_BAND_5G 0x1000
83 | #define WL_CHANSPEC_BAND_2G 0x2000
84 | #define INVCHANSPEC 255
85 |
86 | /* channel defines */
87 | #define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0)
88 | #define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \
89 | ((channel) + CH_10MHZ_APART) : 0)
90 |
91 | #define LL_20_SB(channel) (((channel) > 3 * CH_10MHZ_APART) ? ((channel) - 3 * CH_10MHZ_APART) : 0)
92 | #define UU_20_SB(channel) (((channel) < (MAXCHANNEL - 3 * CH_10MHZ_APART)) ? \
93 | ((channel) + 3 * CH_10MHZ_APART) : 0)
94 | #define LU_20_SB(channel) LOWER_20_SB(channel)
95 | #define UL_20_SB(channel) UPPER_20_SB(channel)
96 |
97 | #define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX)
98 | #define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \
99 | WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \
100 | WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
101 | #define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \
102 | ((channel) + CH_20MHZ_APART) : 0)
103 | #define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
104 | ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \
105 | ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \
106 | WL_CHANSPEC_BAND_5G))
107 | #define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK))
108 | #define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK)
109 |
110 | /* chanspec stores radio channel & flags to indicate control channel location, i.e. upper/lower */
111 | #define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK)
112 | #define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK)
113 |
114 | #ifdef WL11N_20MHZONLY
115 |
116 | #define CHSPEC_IS10(chspec) 0
117 | #define CHSPEC_IS20(chspec) 1
118 | #ifndef CHSPEC_IS40
119 | #define CHSPEC_IS40(chspec) 0
120 | #endif
121 |
122 | #else /* !WL11N_20MHZONLY */
123 |
124 | #define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
125 | #define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
126 | #ifndef CHSPEC_IS40
127 | #define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
128 | #endif
129 |
130 | #endif /* !WL11N_20MHZONLY */
131 |
132 | #define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
133 | #define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
134 | #define CHSPEC_SB_NONE(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE)
135 | #define CHSPEC_SB_UPPER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER)
136 | #define CHSPEC_SB_LOWER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER)
137 | #define CHSPEC_CTL_CHAN(chspec) ((CHSPEC_SB_LOWER(chspec)) ? \
138 | (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \
139 | (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))))
140 | #define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G)
141 |
142 | #define CHANSPEC_STR_LEN 8
143 |
144 | #else /* D11AC_IOTYPES */
145 |
146 | #define WL_CHANSPEC_CHAN_MASK 0x00ff
147 | #define WL_CHANSPEC_CHAN_SHIFT 0
148 | #define WL_CHANSPEC_CHAN1_MASK 0x000f
149 | #define WL_CHANSPEC_CHAN1_SHIFT 0
150 | #define WL_CHANSPEC_CHAN2_MASK 0x00f0
151 | #define WL_CHANSPEC_CHAN2_SHIFT 4
152 |
153 | #define WL_CHANSPEC_CTL_SB_MASK 0x0700
154 | #define WL_CHANSPEC_CTL_SB_SHIFT 8
155 | #define WL_CHANSPEC_CTL_SB_LLL 0x0000
156 | #define WL_CHANSPEC_CTL_SB_LLU 0x0100
157 | #define WL_CHANSPEC_CTL_SB_LUL 0x0200
158 | #define WL_CHANSPEC_CTL_SB_LUU 0x0300
159 | #define WL_CHANSPEC_CTL_SB_ULL 0x0400
160 | #define WL_CHANSPEC_CTL_SB_ULU 0x0500
161 | #define WL_CHANSPEC_CTL_SB_UUL 0x0600
162 | #define WL_CHANSPEC_CTL_SB_UUU 0x0700
163 | #define WL_CHANSPEC_CTL_SB_LL WL_CHANSPEC_CTL_SB_LLL
164 | #define WL_CHANSPEC_CTL_SB_LU WL_CHANSPEC_CTL_SB_LLU
165 | #define WL_CHANSPEC_CTL_SB_UL WL_CHANSPEC_CTL_SB_LUL
166 | #define WL_CHANSPEC_CTL_SB_UU WL_CHANSPEC_CTL_SB_LUU
167 | #define WL_CHANSPEC_CTL_SB_L WL_CHANSPEC_CTL_SB_LLL
168 | #define WL_CHANSPEC_CTL_SB_U WL_CHANSPEC_CTL_SB_LLU
169 | #define WL_CHANSPEC_CTL_SB_LOWER WL_CHANSPEC_CTL_SB_LLL
170 | #define WL_CHANSPEC_CTL_SB_UPPER WL_CHANSPEC_CTL_SB_LLU
171 |
172 | #define WL_CHANSPEC_BW_MASK 0x3800
173 | #define WL_CHANSPEC_BW_SHIFT 11
174 | #define WL_CHANSPEC_BW_5 0x0000
175 | #define WL_CHANSPEC_BW_10 0x0800
176 | #define WL_CHANSPEC_BW_20 0x1000
177 | #define WL_CHANSPEC_BW_40 0x1800
178 | #define WL_CHANSPEC_BW_80 0x2000
179 | #define WL_CHANSPEC_BW_160 0x2800
180 | #define WL_CHANSPEC_BW_8080 0x3000
181 |
182 | #define WL_CHANSPEC_BAND_MASK 0xc000
183 | #define WL_CHANSPEC_BAND_SHIFT 14
184 | #define WL_CHANSPEC_BAND_2G 0x0000
185 | #define WL_CHANSPEC_BAND_3G 0x4000
186 | #define WL_CHANSPEC_BAND_4G 0x8000
187 | #define WL_CHANSPEC_BAND_5G 0xc000
188 | #define INVCHANSPEC 255
189 |
190 | /* channel defines */
191 | #define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? \
192 | ((channel) - CH_10MHZ_APART) : 0)
193 | #define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \
194 | ((channel) + CH_10MHZ_APART) : 0)
195 |
196 | #define LL_20_SB(channel) (((channel) > 3 * CH_10MHZ_APART) ? ((channel) - 3 * CH_10MHZ_APART) : 0)
197 | #define UU_20_SB(channel) (((channel) < (MAXCHANNEL - 3 * CH_10MHZ_APART)) ? \
198 | ((channel) + 3 * CH_10MHZ_APART) : 0)
199 | #define LU_20_SB(channel) LOWER_20_SB(channel)
200 | #define UL_20_SB(channel) UPPER_20_SB(channel)
201 |
202 | #define LOWER_40_SB(channel) ((channel) - CH_20MHZ_APART)
203 | #define UPPER_40_SB(channel) ((channel) + CH_20MHZ_APART)
204 | #define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX)
205 | #define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \
206 | (((channel) <= CH_MAX_2G_CHANNEL) ? \
207 | WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
208 | #define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \
209 | ((channel) + CH_20MHZ_APART) : 0)
210 | #define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
211 | ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \
212 | ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \
213 | WL_CHANSPEC_BAND_5G))
214 | #define CH80MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
215 | ((channel) | (ctlsb) | \
216 | WL_CHANSPEC_BW_80 | WL_CHANSPEC_BAND_5G)
217 | #define CH160MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
218 | ((channel) | (ctlsb) | \
219 | WL_CHANSPEC_BW_160 | WL_CHANSPEC_BAND_5G)
220 |
221 | /* simple MACROs to get different fields of chanspec */
222 | #define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK))
223 | #define CHSPEC_CHAN1(chspec) ((chspec) & WL_CHANSPEC_CHAN1_MASK)
224 | #define CHSPEC_CHAN2(chspec) ((chspec) & WL_CHANSPEC_CHAN2_MASK)
225 | #define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK)
226 | #define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK)
227 | #define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK)
228 |
229 | #ifdef WL11N_20MHZONLY
230 |
231 | #define CHSPEC_IS10(chspec) 0
232 | #define CHSPEC_IS20(chspec) 1
233 | #ifndef CHSPEC_IS40
234 | #define CHSPEC_IS40(chspec) 0
235 | #endif
236 | #ifndef CHSPEC_IS80
237 | #define CHSPEC_IS80(chspec) 0
238 | #endif
239 | #ifndef CHSPEC_IS160
240 | #define CHSPEC_IS160(chspec) 0
241 | #endif
242 | #ifndef CHSPEC_IS8080
243 | #define CHSPEC_IS8080(chspec) 0
244 | #endif
245 |
246 | #else /* !WL11N_20MHZONLY */
247 |
248 | #define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
249 | #define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
250 | #ifndef CHSPEC_IS40
251 | #define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
252 | #endif
253 | #ifndef CHSPEC_IS80
254 | #define CHSPEC_IS80(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80)
255 | #endif
256 | #ifndef CHSPEC_IS160
257 | #define CHSPEC_IS160(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_160)
258 | #endif
259 | #ifndef CHSPEC_IS8080
260 | #define CHSPEC_IS8080(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_8080)
261 | #endif
262 |
263 | #endif /* !WL11N_20MHZONLY */
264 |
265 | #define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
266 | #define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
267 | #define CHSPEC_SB_UPPER(chspec) \
268 | ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) && \
269 | (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40))
270 | #define CHSPEC_SB_LOWER(chspec) \
271 | ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) && \
272 | (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40))
273 | #define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G)
274 |
275 | /**
276 | * Number of chars needed for wf_chspec_ntoa() destination character buffer.
277 | */
278 | #define CHANSPEC_STR_LEN 20
279 |
280 |
281 | /* Legacy Chanspec defines
282 | * These are the defines for the previous format of the chanspec_t
283 | */
284 | #define WL_LCHANSPEC_CHAN_MASK 0x00ff
285 | #define WL_LCHANSPEC_CHAN_SHIFT 0
286 |
287 | #define WL_LCHANSPEC_CTL_SB_MASK 0x0300
288 | #define WL_LCHANSPEC_CTL_SB_SHIFT 8
289 | #define WL_LCHANSPEC_CTL_SB_LOWER 0x0100
290 | #define WL_LCHANSPEC_CTL_SB_UPPER 0x0200
291 | #define WL_LCHANSPEC_CTL_SB_NONE 0x0300
292 |
293 | #define WL_LCHANSPEC_BW_MASK 0x0C00
294 | #define WL_LCHANSPEC_BW_SHIFT 10
295 | #define WL_LCHANSPEC_BW_10 0x0400
296 | #define WL_LCHANSPEC_BW_20 0x0800
297 | #define WL_LCHANSPEC_BW_40 0x0C00
298 |
299 | #define WL_LCHANSPEC_BAND_MASK 0xf000
300 | #define WL_LCHANSPEC_BAND_SHIFT 12
301 | #define WL_LCHANSPEC_BAND_5G 0x1000
302 | #define WL_LCHANSPEC_BAND_2G 0x2000
303 |
304 | #define LCHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_LCHANSPEC_CHAN_MASK))
305 | #define LCHSPEC_BAND(chspec) ((chspec) & WL_LCHANSPEC_BAND_MASK)
306 | #define LCHSPEC_CTL_SB(chspec) ((chspec) & WL_LCHANSPEC_CTL_SB_MASK)
307 | #define LCHSPEC_BW(chspec) ((chspec) & WL_LCHANSPEC_BW_MASK)
308 | #define LCHSPEC_IS10(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_10)
309 | #define LCHSPEC_IS20(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_20)
310 | #define LCHSPEC_IS40(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40)
311 | #define LCHSPEC_IS5G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_5G)
312 | #define LCHSPEC_IS2G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_2G)
313 |
314 | #define LCHSPEC_CREATE(chan, band, bw, sb) ((uint16)((chan) | (sb) | (bw) | (band)))
315 |
316 | #define CH20MHZ_LCHSPEC(channel) \
317 | (chanspec_t)((chanspec_t)(channel) | WL_LCHANSPEC_BW_20 | \
318 | WL_LCHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \
319 | WL_LCHANSPEC_BAND_2G : WL_LCHANSPEC_BAND_5G))
320 |
321 | #endif /* D11AC_IOTYPES */
322 |
323 | /*
324 | * WF_CHAN_FACTOR_* constants are used to calculate channel frequency
325 | * given a channel number.
326 | * chan_freq = chan_factor * 500Mhz + chan_number * 5
327 | */
328 |
329 | /**
330 | * Channel Factor for the starting frequence of 2.4 GHz channels.
331 | * The value corresponds to 2407 MHz.
332 | */
333 | #define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */
334 |
335 | /**
336 | * Channel Factor for the starting frequence of 5 GHz channels.
337 | * The value corresponds to 5000 MHz.
338 | */
339 | #define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */
340 |
341 | /**
342 | * Channel Factor for the starting frequence of 4.9 GHz channels.
343 | * The value corresponds to 4000 MHz.
344 | */
345 | #define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */
346 |
347 | #define WLC_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */
348 |
349 | /**
350 | * Convert chanspec to ascii string
351 | *
352 | * @param chspec chanspec format
353 | * @param buf ascii string of chanspec
354 | *
355 | * @return pointer to buf with room for at least CHANSPEC_STR_LEN bytes
356 | *
357 | * @see CHANSPEC_STR_LEN
358 | */
359 | extern char * wf_chspec_ntoa(chanspec_t chspec, char *buf);
360 |
361 | /**
362 | * Convert ascii string to chanspec
363 | *
364 | * @param a pointer to input string
365 | *
366 | * @return >= 0 if successful or 0 otherwise
367 | */
368 | extern chanspec_t wf_chspec_aton(const char *a);
369 |
370 | /**
371 | * Verify the chanspec fields are valid.
372 | *
373 | * Verify the chanspec is using a legal set field values, i.e. that the chanspec
374 | * specified a band, bw, ctl_sb and channel and that the combination could be
375 | * legal given some set of circumstances.
376 | *
377 | * @param chanspec input chanspec to verify
378 | *
379 | * @return TRUE if the chanspec is malformed, FALSE if it looks good.
380 | */
381 | extern bool wf_chspec_malformed(chanspec_t chanspec);
382 |
383 | /**
384 | * Verify the chanspec specifies a valid channel according to 802.11.
385 | *
386 | * @param chanspec input chanspec to verify
387 | *
388 | * @return TRUE if the chanspec is a valid 802.11 channel
389 | */
390 | extern bool wf_chspec_valid(chanspec_t chanspec);
391 |
392 | /**
393 | * Return the primary (control) channel.
394 | *
395 | * This function returns the channel number of the primary 20MHz channel. For
396 | * 20MHz channels this is just the channel number. For 40MHz or wider channels
397 | * it is the primary 20MHz channel specified by the chanspec.
398 | *
399 | * @param chspec input chanspec
400 | *
401 | * @return Returns the channel number of the primary 20MHz channel
402 | */
403 | extern uint8 wf_chspec_ctlchan(chanspec_t chspec);
404 |
405 | /**
406 | * Return the primary (control) chanspec.
407 | *
408 | * This function returns the chanspec of the primary 20MHz channel. For 20MHz
409 | * channels this is just the chanspec. For 40MHz or wider channels it is the
410 | * chanspec of the primary 20MHZ channel specified by the chanspec.
411 | *
412 | * @param chspec input chanspec
413 | *
414 | * @return Returns the chanspec of the primary 20MHz channel
415 | */
416 | extern chanspec_t wf_chspec_ctlchspec(chanspec_t chspec);
417 |
418 | /**
419 | * Return a channel number corresponding to a frequency.
420 | *
421 | * This function returns the chanspec for the primary 40MHz of an 80MHz channel.
422 | * The control sideband specifies the same 20MHz channel that the 80MHz channel is using
423 | * as the primary 20MHz channel.
424 | */
425 | extern chanspec_t wf_chspec_primary40_chspec(chanspec_t chspec);
426 |
427 | /*
428 | * Return the channel number for a given frequency and base frequency.
429 | * The returned channel number is relative to the given base frequency.
430 | * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
431 | * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
432 | *
433 | * Frequency is specified in MHz.
434 | * The base frequency is specified as (start_factor * 500 kHz).
435 | * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
436 | * 2.4 GHz and 5 GHz bands.
437 | *
438 | * The returned channel will be in the range [1, 14] in the 2.4 GHz band
439 | * and [0, 200] otherwise.
440 | * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
441 | * frequency is not a 2.4 GHz channel, or if the frequency is not and even
442 | * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
443 | *
444 | * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
445 | *
446 | * @param freq frequency in MHz
447 | * @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz
448 | *
449 | * @return Returns a channel number
450 | *
451 | * @see WF_CHAN_FACTOR_2_4_G
452 | * @see WF_CHAN_FACTOR_5_G
453 | */
454 | extern int wf_mhz2channel(uint freq, uint start_factor);
455 |
456 | /**
457 | * Return the center frequency in MHz of the given channel and base frequency.
458 | *
459 | * Return the center frequency in MHz of the given channel and base frequency.
460 | * The channel number is interpreted relative to the given base frequency.
461 | *
462 | * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise.
463 | * The base frequency is specified as (start_factor * 500 kHz).
464 | * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
465 | * 2.4 GHz and 5 GHz bands.
466 | * The channel range of [1, 14] is only checked for a start_factor of
467 | * WF_CHAN_FACTOR_2_4_G (4814).
468 | * Odd start_factors produce channels on .5 MHz boundaries, in which case
469 | * the answer is rounded down to an integral MHz.
470 | * -1 is returned for an out of range channel.
471 | *
472 | * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
473 | *
474 | * @param channel input channel number
475 | * @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz
476 | *
477 | * @return Returns a frequency in MHz
478 | *
479 | * @see WF_CHAN_FACTOR_2_4_G
480 | * @see WF_CHAN_FACTOR_5_G
481 | */
482 | extern int wf_channel2mhz(uint channel, uint start_factor);
483 |
484 | /**
485 | * Convert ctl chan and bw to chanspec
486 | *
487 | * @param ctl_ch channel
488 | * @param bw bandwidth
489 | *
490 | * @return > 0 if successful or 0 otherwise
491 | *
492 | */
493 | extern uint16 wf_channel2chspec(uint ctl_ch, uint bw);
494 |
495 | extern uint wf_channel2freq(uint channel);
496 | extern uint wf_freq2channel(uint freq);
497 |
498 |
499 | #endif /* _bcmwifi_channels_h_ */
500 |
--------------------------------------------------------------------------------
/libnexio.c:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * *
3 | * ########### ########### ########## ########## *
4 | * ############ ############ ############ ############ *
5 | * ## ## ## ## ## ## ## *
6 | * ## ## ## ## ## ## ## *
7 | * ########### #### ###### ## ## ## ## ###### *
8 | * ########### #### # ## ## ## ## # # *
9 | * ## ## ###### ## ## ## ## # # *
10 | * ## ## # ## ## ## ## # # *
11 | * ############ ##### ###### ## ## ## ##### ###### *
12 | * ########### ########### ## ## ## ########## *
13 | * *
14 | * S E C U R E M O B I L E N E T W O R K I N G *
15 | * *
16 | * This file is part of NexMon. *
17 | * *
18 | * Copyright (c) 2016 NexMon Team *
19 | * *
20 | * NexMon is free software: you can redistribute it and/or modify *
21 | * it under the terms of the GNU General Public License as published by *
22 | * the Free Software Foundation, either version 3 of the License, or *
23 | * (at your option) any later version. *
24 | * *
25 | * NexMon is distributed in the hope that it will be useful, *
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
28 | * GNU General Public License for more details. *
29 | * *
30 | * You should have received a copy of the GNU General Public License *
31 | * along with NexMon. If not, see . *
32 | * *
33 | **************************************************************************/
34 |
35 | #include
36 | #include
37 | #include
38 | #include
39 |
40 | #include
41 | #include
42 | #include
43 | #include
44 |
45 | #include
46 | #ifdef BUILD_ON_RPI
47 | #include
48 | #else
49 | #include
50 | #endif
51 | #include
52 | #include
53 |
54 | #include
55 | #include
56 |
57 | #include
58 |
59 | #define WLC_IOCTL_MAGIC 0x14e46c77
60 | #define DHD_IOCTL_MAGIC 0x00444944
61 |
62 | #define WLC_GET_MAGIC 0
63 | #define DHD_GET_MAGIC 0
64 |
65 | #define NEXUDP_IOCTL 0
66 | #define NEXUDP_INJECT_RADIOTAP 1
67 |
68 | #define NETLINK_USER 31
69 |
70 | #define IPADDR(a,b,c,d) ((d) << 24 | (c) << 16 | (b) << 8 | (a))
71 |
72 | #define NEXIO_TYPE_IOCTL 0
73 | #define NEXIO_TYPE_UDP 1
74 | #define NEXIO_TYPE_NETLINK 2
75 |
76 | struct nexio {
77 | int type;
78 | struct ifreq *ifr;
79 | int sock_rx_ioctl;
80 | int sock_rx_frame;
81 | int sock_tx;
82 | unsigned int securitycookie;
83 | };
84 |
85 | struct nex_ioctl {
86 | unsigned int cmd; /* common ioctl definition */
87 | void *buf; /* pointer to user buffer */
88 | unsigned int len; /* length of user buffer */
89 | bool set; /* get or set request (optional) */
90 | unsigned int used; /* bytes read or written (optional) */
91 | unsigned int needed; /* bytes needed (optional) */
92 | unsigned int driver; /* to identify target driver */
93 | };
94 |
95 | struct nexudp_header {
96 | char nex[3];
97 | char type;
98 | int securitycookie;
99 | } __attribute__((packed));
100 |
101 | struct nexudp_ioctl_header {
102 | struct nexudp_header nexudphdr;
103 | unsigned int cmd;
104 | unsigned int set;
105 | char payload[1];
106 | } __attribute__((packed));
107 |
108 |
109 | static int
110 | __nex_driver_io(struct ifreq *ifr, struct nex_ioctl *ioc)
111 | {
112 | int s;
113 | int ret = 0;
114 |
115 | /* pass ioctl data */
116 | ifr->ifr_data = (void *) ioc;
117 |
118 | /* open socket to kernel */
119 | if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
120 | fprintf(stderr, "error: socket\n");
121 |
122 | ret = ioctl(s, SIOCDEVPRIVATE, ifr);
123 | if (ret < 0 && errno != EAGAIN)
124 | fprintf(stderr, "%s: error (%d: %s)\n", __FUNCTION__, errno, strerror(errno));
125 |
126 | /* cleanup */
127 | close(s);
128 | return ret;
129 | }
130 |
131 | static int
132 | __nex_driver_udp(struct nexio *nexio, struct nex_ioctl *ioc)
133 | {
134 | int frame_len = ioc->len + sizeof(struct nexudp_ioctl_header) - sizeof(char);
135 | int rx_frame_len = 0;
136 | struct nexudp_ioctl_header *frame = (struct nexudp_ioctl_header *) malloc(frame_len);
137 | int ret = 0;
138 |
139 | memcpy(&frame->nexudphdr.nex, "NEX", 3);
140 | frame->nexudphdr.type = NEXUDP_IOCTL;
141 | frame->nexudphdr.securitycookie = nexio->securitycookie;
142 |
143 | frame->cmd = ioc->cmd;
144 | frame->set = ioc->set;
145 |
146 | memcpy(frame->payload, ioc->buf, ioc->len);
147 |
148 | send(nexio->sock_tx, frame, frame_len, 0);
149 |
150 | rx_frame_len = recv(nexio->sock_rx_ioctl, frame, frame_len, 0);
151 |
152 | if (ioc->set == 0 && rx_frame_len > 0 && *(unsigned int *) frame == ioc->cmd) {
153 | memcpy(ioc->buf, ((char *) frame) + sizeof(frame->cmd) + sizeof(frame->set),
154 | (rx_frame_len - sizeof(frame->cmd) - sizeof(frame->set)) < ioc->len ?
155 | (rx_frame_len - sizeof(frame->cmd) - sizeof(frame->set)) : ioc->len);
156 | }
157 |
158 | free(frame);
159 |
160 | if (rx_frame_len < 0) {
161 | ret = -1;
162 | fprintf(stderr, "ERR (%s): no valid answer received\n", __FUNCTION__);
163 | }
164 |
165 | return ret;
166 | }
167 |
168 | static int
169 | __nex_driver_netlink(struct nexio *nexio, struct nex_ioctl *ioc)
170 | {
171 | int frame_len = ioc->len + sizeof(struct nexudp_ioctl_header) - sizeof(char);
172 | int rx_frame_len = 0;
173 | struct nexudp_ioctl_header *frame;
174 | int ret = 0;
175 |
176 | struct iovec iov = { 0 };
177 | struct msghdr msg = { 0 };
178 |
179 | struct nlmsghdr *nlh = (struct nlmsghdr *) malloc(NLMSG_SPACE(frame_len));
180 | memset(nlh, 0, NLMSG_SPACE(frame_len));
181 | nlh->nlmsg_len = NLMSG_SPACE(frame_len);
182 | nlh->nlmsg_pid = getpid();
183 | nlh->nlmsg_flags = 0;
184 | frame = (struct nexudp_ioctl_header *) NLMSG_DATA(nlh);
185 |
186 | memcpy(&frame->nexudphdr.nex, "NEX", 3);
187 | frame->nexudphdr.type = NEXUDP_IOCTL;
188 | frame->nexudphdr.securitycookie = nexio->securitycookie;
189 |
190 | frame->cmd = ioc->cmd;
191 | frame->set = ioc->set;
192 |
193 | memcpy(frame->payload, ioc->buf, ioc->len);
194 |
195 | // printf("%s: before send. nlh->nlmsg_len: %d ioc->len: %d\n", __FUNCTION__, nlh->nlmsg_len, ioc->len);
196 | send(nexio->sock_tx, nlh, nlh->nlmsg_len, 0);
197 |
198 | rx_frame_len = recv(nexio->sock_rx_ioctl, nlh, nlh->nlmsg_len, 0);
199 |
200 | // printf("%s: framelen %d %d %s\n", __FUNCTION__, rx_frame_len, nlh->nlmsg_len, (char *) frame);
201 |
202 | if (ioc->set == 0 && rx_frame_len > 0 && frame->cmd == ioc->cmd) {
203 | memcpy(ioc->buf, frame->payload,
204 | (rx_frame_len - sizeof(struct nexudp_ioctl_header) + sizeof(char)) < ioc->len ?
205 | (rx_frame_len - sizeof(struct nexudp_ioctl_header) + sizeof(char)) : ioc->len);
206 | }
207 |
208 | free(nlh);
209 |
210 | if (rx_frame_len < 0) {
211 | ret = -1;
212 | fprintf(stderr, "ERR (%s): no valid answer received\n", __FUNCTION__);
213 | }
214 |
215 | return ret;
216 | }
217 |
218 | /* This function is called by ioctl_setinformation_fe or ioctl_queryinformation_fe
219 | * for executing remote commands or local commands
220 | */
221 | int
222 | nex_ioctl(struct nexio *nexio, int cmd, void *buf, int len, bool set)
223 | {
224 | struct nex_ioctl ioc;
225 | int ret = 0;
226 |
227 | /* do it */
228 | ioc.cmd = cmd;
229 | ioc.buf = buf;
230 | ioc.len = len;
231 | ioc.set = set;
232 | ioc.driver = WLC_IOCTL_MAGIC;
233 |
234 |
235 | if (nexio != 0) {
236 | switch(nexio->type) {
237 | case NEXIO_TYPE_IOCTL:
238 | ret = __nex_driver_io(nexio->ifr, &ioc);
239 | break;
240 | case NEXIO_TYPE_UDP:
241 | ret = __nex_driver_udp(nexio, &ioc);
242 | break;
243 | case NEXIO_TYPE_NETLINK:
244 | ret = __nex_driver_netlink(nexio, &ioc);
245 | break;
246 | default:
247 | fprintf(stderr, "%s: not initialized correctly\n", __FUNCTION__);
248 | }
249 | } else {
250 | fprintf(stderr, "%s: not initialized\n", __FUNCTION__);
251 | }
252 |
253 | if (ret < 0 && cmd != WLC_GET_MAGIC)
254 | ret = -1;
255 |
256 | return ret;
257 | }
258 |
259 | struct nexio *
260 | nex_init_ioctl(const char *ifname)
261 | {
262 | struct nexio *nexio = (struct nexio *) malloc(sizeof(struct nexio));
263 | memset(nexio, 0, sizeof(struct nexio));
264 |
265 | nexio->ifr = (struct ifreq *) malloc(sizeof(struct ifreq));
266 | memset(nexio->ifr, 0, sizeof(struct ifreq));
267 | snprintf(nexio->ifr->ifr_name, sizeof(nexio->ifr->ifr_name), "%s", ifname);
268 |
269 | nexio->type = NEXIO_TYPE_IOCTL;
270 |
271 | return nexio;
272 | }
273 |
274 | struct nexio *
275 | nex_init_udp(unsigned int securitycookie, unsigned int txip)
276 | {
277 | struct nexio *nexio = (struct nexio *) malloc(sizeof(struct nexio));
278 | memset(nexio, 0, sizeof(struct nexio));
279 |
280 | nexio->securitycookie = securitycookie;
281 |
282 | struct sockaddr_in *sin_tx = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
283 | struct sockaddr_in *sin_rx_ioctl = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
284 | struct sockaddr_in *sin_rx_frame = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in));
285 |
286 | memset(sin_tx, 0, sizeof(struct sockaddr_in));
287 | memset(sin_rx_ioctl, 0, sizeof(struct sockaddr_in));
288 | memset(sin_rx_frame, 0, sizeof(struct sockaddr_in));
289 |
290 | sin_tx->sin_family = AF_INET;
291 | sin_tx->sin_port = htons(5500);
292 | sin_tx->sin_addr.s_addr = txip;
293 |
294 | sin_rx_ioctl->sin_family = AF_INET;
295 | sin_rx_ioctl->sin_port = htons(5500);
296 | sin_rx_ioctl->sin_addr.s_addr = IPADDR(255,255,255,255);
297 |
298 | sin_rx_frame->sin_family = AF_INET;
299 | sin_rx_frame->sin_port = htons(5600);
300 | sin_rx_frame->sin_addr.s_addr = IPADDR(255,255,255,255);
301 |
302 | nexio->sock_tx = socket(sin_tx->sin_family, SOCK_DGRAM, IPPROTO_UDP);
303 | nexio->sock_rx_ioctl = socket(sin_rx_ioctl->sin_family, SOCK_DGRAM, IPPROTO_UDP);
304 | nexio->sock_rx_frame = socket(sin_rx_frame->sin_family, SOCK_DGRAM, IPPROTO_UDP);
305 |
306 | // Enable broadcasts for transmit socket
307 | int broadcast_enable = 1;
308 | setsockopt(nexio->sock_tx, SOL_SOCKET, SO_BROADCAST, &broadcast_enable, sizeof(broadcast_enable));
309 |
310 | // Set 1 second timeout on ioctl receive socket
311 | struct timeval tv = {
312 | .tv_sec = 1,
313 | .tv_usec = 0
314 | };
315 | setsockopt(nexio->sock_rx_ioctl, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
316 |
317 | connect(nexio->sock_tx, (struct sockaddr *) sin_tx, sizeof(struct sockaddr));
318 | bind(nexio->sock_rx_ioctl, (struct sockaddr *) sin_rx_ioctl, sizeof(struct sockaddr));
319 | bind(nexio->sock_rx_frame, (struct sockaddr *) sin_rx_frame, sizeof(struct sockaddr));
320 |
321 | nexio->type = NEXIO_TYPE_UDP;
322 |
323 | return nexio;
324 | }
325 |
326 | struct nexio *
327 | nex_init_netlink(void)
328 | {
329 | // printf("%s: Enter\n", __FUNCTION__);
330 | int err = 0;
331 | struct nexio *nexio = (struct nexio *) malloc(sizeof(struct nexio));
332 | memset(nexio, 0, sizeof(struct nexio));
333 |
334 | struct sockaddr_nl *snl_tx = (struct sockaddr_nl *) malloc(sizeof(struct sockaddr_nl));
335 | struct sockaddr_nl *snl_rx_ioctl = (struct sockaddr_nl *) malloc(sizeof(struct sockaddr_nl));
336 |
337 | memset(snl_tx, 0, sizeof(struct sockaddr_nl));
338 | memset(snl_rx_ioctl, 0, sizeof(struct sockaddr_nl));
339 |
340 | snl_tx->nl_family = AF_NETLINK;
341 | snl_tx->nl_pid = 0; /* For Linux Kernel */
342 | snl_tx->nl_groups = 0; /* unicast */
343 |
344 | snl_rx_ioctl->nl_family = AF_NETLINK;
345 | snl_rx_ioctl->nl_pid = getpid();
346 |
347 | nexio->sock_tx = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
348 | if (nexio->sock_tx < 0) fprintf(stderr, "%s: socket error (%d: %s)\n", __FUNCTION__, errno, strerror(errno));
349 | nexio->sock_rx_ioctl = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
350 | if (nexio->sock_rx_ioctl < 0) fprintf(stderr, "%s: socket error (%d: %s)\n", __FUNCTION__, errno, strerror(errno));
351 |
352 | // Set 1 second timeout on ioctl receive socket
353 | struct timeval tv = {
354 | .tv_sec = 1,
355 | .tv_usec = 0
356 | };
357 | setsockopt(nexio->sock_rx_ioctl, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
358 |
359 | // printf("%s: Before connect\n", __FUNCTION__);
360 | err = bind(nexio->sock_rx_ioctl, (struct sockaddr *) snl_rx_ioctl, sizeof(struct sockaddr));
361 | if (err) fprintf(stderr, "%s: bind error (%d: %s)\n", __FUNCTION__, errno, strerror(errno));
362 |
363 | err = connect(nexio->sock_tx, (struct sockaddr *) snl_tx, sizeof(struct sockaddr));
364 | if (err) fprintf(stderr, "%s: connect error (%d: %s)\n", __FUNCTION__, errno, strerror(errno));
365 |
366 | // printf("%s: Exit\n", __FUNCTION__);
367 |
368 | nexio->type = NEXIO_TYPE_NETLINK;
369 |
370 | return nexio;
371 | }
372 |
--------------------------------------------------------------------------------
/monitormode.h:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * *
3 | * ########### ########### ########## ########## *
4 | * ############ ############ ############ ############ *
5 | * ## ## ## ## ## ## ## *
6 | * ## ## ## ## ## ## ## *
7 | * ########### #### ###### ## ## ## ## ###### *
8 | * ########### #### # ## ## ## ## # # *
9 | * ## ## ###### ## ## ## ## # # *
10 | * ## ## # ## ## ## ## # # *
11 | * ############ ##### ###### ## ## ## ##### ###### *
12 | * ########### ########### ## ## ## ########## *
13 | * *
14 | * S E C U R E M O B I L E N E T W O R K I N G *
15 | * *
16 | * This file is part of NexMon. *
17 | * *
18 | * Copyright (c) 2016 NexMon Team *
19 | * *
20 | * NexMon is free software: you can redistribute it and/or modify *
21 | * it under the terms of the GNU General Public License as published by *
22 | * the Free Software Foundation, either version 3 of the License, or *
23 | * (at your option) any later version. *
24 | * *
25 | * NexMon is distributed in the hope that it will be useful, *
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
28 | * GNU General Public License for more details. *
29 | * *
30 | * You should have received a copy of the GNU General Public License *
31 | * along with NexMon. If not, see . *
32 | * *
33 | **************************************************************************/
34 |
35 | #define MONITOR_DISABLED 0
36 | #define MONITOR_IEEE80211 (1 << 0) // 1
37 | #define MONITOR_RADIOTAP (1 << 1) // 2
38 | #define MONITOR_DROP_FRM (1 << 2) // 4
39 | #define MONITOR_IPV4_UDP (1 << 3) // 8
40 | #define MONITOR_LOG_ONLY (1 << 4) // 16
41 | #define MONITOR_ACTIVATE_BADFCS (1 << 5) // 32
42 | #define MONITOR_STS (1 << 6) // 64
43 |
--------------------------------------------------------------------------------
/nexioctls.h:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * *
3 | * ########### ########### ########## ########## *
4 | * ############ ############ ############ ############ *
5 | * ## ## ## ## ## ## ## *
6 | * ## ## ## ## ## ## ## *
7 | * ########### #### ###### ## ## ## ## ###### *
8 | * ########### #### # ## ## ## ## # # *
9 | * ## ## ###### ## ## ## ## # # *
10 | * ## ## # ## ## ## ## # # *
11 | * ############ ##### ###### ## ## ## ##### ###### *
12 | * ########### ########### ## ## ## ########## *
13 | * *
14 | * S E C U R E M O B I L E N E T W O R K I N G *
15 | * *
16 | * This file is part of NexMon. *
17 | * *
18 | * Copyright (c) 2016 NexMon Team *
19 | * *
20 | * NexMon is free software: you can redistribute it and/or modify *
21 | * it under the terms of the GNU General Public License as published by *
22 | * the Free Software Foundation, either version 3 of the License, or *
23 | * (at your option) any later version. *
24 | * *
25 | * NexMon is distributed in the hope that it will be useful, *
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
28 | * GNU General Public License for more details. *
29 | * *
30 | * You should have received a copy of the GNU General Public License *
31 | * along with NexMon. If not, see . *
32 | * *
33 | **************************************************************************/
34 |
35 | #define IOCTL_ERROR -23
36 | #define IOCTL_SUCCESS 0
37 |
38 | // IOCTLs used by Nexmon
39 | #define NEX_GET_CAPABILITIES 400
40 | #define NEX_WRITE_TO_CONSOLE 401
41 | #define NEX_CT_EXPERIMENTS 402
42 | #define NEX_GET_CONSOLE 403
43 | #define NEX_GET_PHYREG 404
44 | #define NEX_SET_PHYREG 405
45 | #define NEX_READ_OBJMEM 406
46 | #define NEX_WRITE_OBJMEM 407
47 | #define NEX_INJECT_FRAME 408
48 | #define NEX_PRINT_TIMERS 409
49 | #define NEX_GET_SECURITYCOOKIE 410
50 | #define NEX_SET_SECURITYCOOKIE 411
51 | #define NEX_GET_WL_CNT 412
52 | #define NEX_GET_VERSION_STRING 413
53 | #define NEX_TEST_ARGPRINTF 414
54 | #define NEX_GET_RSPEC_OVERRIDE 415
55 | #define NEX_SET_RSPEC_OVERRIDE 416
56 | #define NEX_CLEAR_CONSOLE 417
57 | #define NEX_GET_CHANSPEC_OVERRIDE 418
58 | #define NEX_SET_CHANSPEC_OVERRIDE 419
59 | #define NEX_GET_AMPDU_TX 420
60 | #define NEX_SET_AMPDU_TX 421
61 | #define NEX_TRIGGER_EVENT 422
62 | #define NEX_TRIGGER_TDLS_DISCOVER 423
63 | #define NEX_TRIGGER_TDLS_SETUP 424
64 | #define NEX_TRIGGER_TDLS_TEARDOWN 425
65 | #define NEX_WRITE_TEMPLATE_RAM 426
66 | #define NEX_SDR_START_TRANSMISSION 427
67 | #define NEX_SDR_STOP_TRANSMISSION 428
68 |
69 |
70 | // IOCTLs used in original firmware
71 | #define WLC_GET_MAGIC 0
72 | #define WLC_GET_VERSION 1
73 | #define WLC_UP 2
74 | #define WLC_DOWN 3
75 | #define WLC_GET_LOOP 4
76 | #define WLC_SET_LOOP 5
77 | #define WLC_DUMP 6
78 | #define WLC_GET_MSGLEVEL 7
79 | #define WLC_SET_MSGLEVEL 8
80 | #define WLC_GET_PROMISC 9
81 | #define WLC_SET_PROMISC 10
82 | #define WLC_OVERLAY_IOCTL 11
83 | #define WLC_GET_RATE 12
84 | #define WLC_GET_MAX_RATE 13
85 | #define WLC_GET_INSTANCE 14
86 | #define WLC_GET_FRAG 15
87 | #define WLC_SET_FRAG 16
88 | #define WLC_GET_RTS 17
89 | #define WLC_SET_RTS 18
90 | #define NEX_READ_D11_OBJMEM 15
91 | #define WLC_GET_INFRA 19
92 | #define WLC_SET_INFRA 20
93 | #define WLC_GET_AUTH 21
94 | #define WLC_SET_AUTH 22
95 | #define WLC_GET_BSSID 23
96 | #define WLC_SET_BSSID 24
97 | #define WLC_GET_SSID 25
98 | #define WLC_SET_SSID 26
99 | #define WLC_RESTART 27
100 | #define WLC_TERMINATED 28
101 | #define WLC_GET_CHANNEL 29
102 | #define WLC_SET_CHANNEL 30
103 | #define WLC_GET_SRL 31
104 | #define WLC_SET_SRL 32
105 | #define WLC_GET_LRL 33
106 | #define WLC_SET_LRL 34
107 | #define WLC_GET_PLCPHDR 35
108 | #define WLC_SET_PLCPHDR 36
109 | #define WLC_GET_RADIO 37
110 | #define WLC_SET_RADIO 38
111 | #define WLC_GET_PHYTYPE 39
112 | #define WLC_DUMP_RATE 40
113 | #define WLC_SET_RATE_PARAMS 41
114 | #define WLC_GET_FIXRATE 42
115 | #define WLC_SET_FIXRATE 43
116 | #define WLC_GET_KEY 44
117 | #define WLC_SET_KEY 45
118 | #define WLC_GET_REGULATORY 46
119 | #define WLC_SET_REGULATORY 47
120 | #define WLC_GET_PASSIVE_SCAN 48
121 | #define WLC_SET_PASSIVE_SCAN 49
122 | #define WLC_SCAN 50
123 | #define WLC_SCAN_RESULTS 51
124 | #define WLC_DISASSOC 52
125 | #define WLC_REASSOC 53
126 | #define WLC_GET_ROAM_TRIGGER 54
127 | #define WLC_SET_ROAM_TRIGGER 55
128 | #define WLC_GET_ROAM_DELTA 56
129 | #define WLC_SET_ROAM_DELTA 57
130 | #define WLC_GET_ROAM_SCAN_PERIOD 58
131 | #define WLC_SET_ROAM_SCAN_PERIOD 59
132 | #define WLC_EVM 60
133 | #define WLC_GET_TXANT 61
134 | #define WLC_SET_TXANT 62
135 | #define WLC_GET_ANTDIV 63
136 | #define WLC_SET_ANTDIV 64
137 | #define WLC_GET_TXPWR 65
138 | #define WLC_SET_TXPWR 66
139 | #define WLC_GET_CLOSED 67
140 | #define WLC_SET_CLOSED 68
141 | #define WLC_GET_MACLIST 69
142 | #define WLC_SET_MACLIST 70
143 | #define WLC_GET_RATESET 71
144 | #define WLC_SET_RATESET 72
145 | #define WLC_GET_LOCALE 73
146 | #define WLC_LONGTRAIN 74
147 | #define WLC_GET_BCNPRD 75
148 | #define WLC_SET_BCNPRD 76
149 | #define WLC_GET_DTIMPRD 77
150 | #define WLC_SET_DTIMPRD 78
151 | #define WLC_GET_SROM 79
152 | #define WLC_SET_SROM 80
153 | #define WLC_GET_WEP_RESTRICT 81
154 | #define WLC_SET_WEP_RESTRICT 82
155 | #define WLC_GET_COUNTRY 83
156 | #define WLC_SET_COUNTRY 84
157 | #define WLC_GET_PM 85
158 | #define WLC_SET_PM 86
159 | #define WLC_GET_WAKE 87
160 | #define WLC_SET_WAKE 88
161 | #define WLC_GET_D11CNTS 89
162 | #define WLC_GET_FORCELINK 90
163 | #define WLC_SET_FORCELINK 91
164 | #define WLC_FREQ_ACCURACY 92
165 | #define WLC_CARRIER_SUPPRESS 93
166 | #define WLC_GET_PHYREG 94
167 | #define WLC_SET_PHYREG 95
168 | #define WLC_GET_RADIOREG 96
169 | #define WLC_SET_RADIOREG 97
170 | #define WLC_GET_REVINFO 98
171 | #define WLC_GET_UCANTDIV 99
172 | #define WLC_SET_UCANTDIV 100
173 | #define WLC_R_REG 101
174 | #define WLC_W_REG 102
175 | #define WLC_DIAG_LOOPBACK 103
176 | #define WLC_RESET_D11CNTS 104
177 | #define WLC_GET_MACMODE 105
178 | #define WLC_SET_MACMODE 106
179 | #define WLC_GET_MONITOR 107
180 | #define WLC_SET_MONITOR 108
181 | #define WLC_GET_GMODE 109
182 | #define WLC_SET_GMODE 110
183 | #define WLC_GET_LEGACY_ERP 111
184 | #define WLC_SET_LEGACY_ERP 112
185 | #define WLC_GET_RX_ANT 113
186 | #define WLC_GET_CURR_RATESET 114
187 | #define WLC_GET_SCANSUPPRESS 115
188 | #define WLC_SET_SCANSUPPRESS 116
189 | #define WLC_GET_AP 117
190 | #define WLC_SET_AP 118
191 | #define WLC_GET_EAP_RESTRICT 119
192 | #define WLC_SET_EAP_RESTRICT 120
193 | #define WLC_SCB_AUTHORIZE 121
194 | #define WLC_SCB_DEAUTHORIZE 122
195 | #define WLC_GET_WDSLIST 123
196 | #define WLC_SET_WDSLIST 124
197 | #define WLC_GET_ATIM 125
198 | #define WLC_SET_ATIM 126
199 | #define WLC_GET_RSSI 127
200 | #define WLC_GET_PHYANTDIV 128
201 | #define WLC_SET_PHYANTDIV 129
202 | #define WLC_AP_RX_ONLY 130
203 | #define WLC_GET_TX_PATH_PWR 131
204 | #define WLC_SET_TX_PATH_PWR 132
205 | #define WLC_GET_WSEC 133
206 | #define WLC_SET_WSEC 134
207 | #define WLC_GET_PHY_NOISE 135
208 | #define WLC_GET_BSS_INFO 136
209 | #define WLC_GET_PKTCNTS 137
210 | #define WLC_GET_LAZYWDS 138
211 | #define WLC_SET_LAZYWDS 139
212 | #define WLC_GET_BANDLIST 140
213 | #define WLC_GET_BAND 141
214 | #define WLC_SET_BAND 142
215 | #define WLC_SCB_DEAUTHENTICATE 143
216 | #define WLC_GET_SHORTSLOT 144
217 | #define WLC_GET_SHORTSLOT_OVERRIDE 145
218 | #define WLC_SET_SHORTSLOT_OVERRIDE 146
219 | #define WLC_GET_SHORTSLOT_RESTRICT 147
220 | #define WLC_SET_SHORTSLOT_RESTRICT 148
221 | #define WLC_GET_GMODE_PROTECTION 149
222 | #define WLC_GET_GMODE_PROTECTION_OVERRIDE 150
223 | #define WLC_SET_GMODE_PROTECTION_OVERRIDE 151
224 | #define WLC_UPGRADE 152
225 | #define WLC_GET_MRATE 153
226 | #define WLC_SET_MRATE 154
227 | #define WLC_GET_IGNORE_BCNS 155
228 | #define WLC_SET_IGNORE_BCNS 156
229 | #define WLC_GET_SCB_TIMEOUT 157
230 | #define WLC_SET_SCB_TIMEOUT 158
231 | #define WLC_GET_ASSOCLIST 159
232 | #define WLC_GET_CLK 160
233 | #define WLC_SET_CLK 161
234 | #define WLC_GET_UP 162
235 | #define WLC_OUT 163
236 | #define WLC_GET_WPA_AUTH 164
237 | #define WLC_SET_WPA_AUTH 165
238 | #define WLC_GET_UCFLAGS 166
239 | #define WLC_SET_UCFLAGS 167
240 | #define WLC_GET_PWRIDX 168
241 | #define WLC_SET_PWRIDX 169
242 | #define WLC_GET_TSSI 170
243 | #define WLC_GET_SUP_RATESET_OVERRIDE 171
244 | #define WLC_SET_SUP_RATESET_OVERRIDE 172
245 | #define WLC_SET_FAST_TIMER 173
246 | #define WLC_GET_FAST_TIMER 174
247 | #define WLC_SET_SLOW_TIMER 175
248 | #define WLC_GET_SLOW_TIMER 176
249 | #define WLC_DUMP_PHYREGS 177
250 | #define WLC_GET_PROTECTION_CONTROL 178
251 | #define WLC_SET_PROTECTION_CONTROL 179
252 | #define WLC_GET_PHYLIST 180
253 | #define WLC_ENCRYPT_STRENGTH 181
254 | #define WLC_DECRYPT_STATUS 182
255 | #define WLC_GET_KEY_SEQ 183
256 | #define WLC_GET_SCAN_CHANNEL_TIME 184
257 | #define WLC_SET_SCAN_CHANNEL_TIME 185
258 | #define WLC_GET_SCAN_UNASSOC_TIME 186
259 | #define WLC_SET_SCAN_UNASSOC_TIME 187
260 | #define WLC_GET_SCAN_HOME_TIME 188
261 | #define WLC_SET_SCAN_HOME_TIME 189
262 | #define WLC_GET_SCAN_NPROBES 190
263 | #define WLC_SET_SCAN_NPROBES 191
264 | #define WLC_GET_PRB_RESP_TIMEOUT 192
265 | #define WLC_SET_PRB_RESP_TIMEOUT 193
266 | #define WLC_GET_ATTEN 194
267 | #define WLC_SET_ATTEN 195
268 | #define WLC_GET_SHMEM 196
269 | #define WLC_SET_SHMEM 197
270 | #define WLC_GET_GMODE_PROTECTION_CTS 198
271 | #define WLC_SET_GMODE_PROTECTION_CTS 199
272 | #define WLC_SET_WSEC_TEST 200
273 | #define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201
274 | #define WLC_TKIP_COUNTERMEASURES 202
275 | #define WLC_GET_PIOMODE 203
276 | #define WLC_SET_PIOMODE 204
277 | #define WLC_SET_ASSOC_PREFER 205
278 | #define WLC_GET_ASSOC_PREFER 206
279 | #define WLC_SET_ROAM_PREFER 207
280 | #define WLC_GET_ROAM_PREFER 208
281 | #define WLC_SET_LED 209
282 | #define WLC_GET_LED 210
283 | #define WLC_GET_INTERFERENCE_MODE 211
284 | #define WLC_SET_INTERFERENCE_MODE 212
285 | #define WLC_GET_CHANNEL_QA 213
286 | #define WLC_START_CHANNEL_QA 214
287 | #define WLC_GET_CHANNEL_SEL 215
288 | #define WLC_START_CHANNEL_SEL 216
289 | #define WLC_GET_VALID_CHANNELS 217
290 | #define WLC_GET_FAKEFRAG 218
291 | #define WLC_SET_FAKEFRAG 219
292 | #define WLC_GET_PWROUT_PERCENTAGE 220
293 | #define WLC_SET_PWROUT_PERCENTAGE 221
294 | #define WLC_SET_BAD_FRAME_PREEMPT 222
295 | #define WLC_GET_BAD_FRAME_PREEMPT 223
296 | #define WLC_SET_LEAP_LIST 224
297 | #define WLC_GET_LEAP_LIST 225
298 | #define WLC_GET_CWMIN 226
299 | #define WLC_SET_CWMIN 227
300 | #define WLC_GET_CWMAX 228
301 | #define WLC_SET_CWMAX 229
302 | #define WLC_GET_WET 230
303 | #define WLC_SET_WET 231
304 | #define WLC_GET_PUB 232
305 | #define WLC_GET_KEY_PRIMARY 235
306 | #define WLC_SET_KEY_PRIMARY 236
307 | #define WLC_GET_VAR 262 /* get value of named variable */
308 | #define WLC_SET_VAR 263 /* set named variable to value */
309 |
--------------------------------------------------------------------------------
/nexmon.c:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * *
3 | * ########### ########### ########## ########## *
4 | * ############ ############ ############ ############ *
5 | * ## ## ## ## ## ## ## *
6 | * ## ## ## ## ## ## ## *
7 | * ########### #### ###### ## ## ## ## ###### *
8 | * ########### #### # ## ## ## ## # # *
9 | * ## ## ###### ## ## ## ## # # *
10 | * ## ## # ## ## ## ## # # *
11 | * ############ ##### ###### ## ## ## ##### ###### *
12 | * ########### ########### ## ## ## ########## *
13 | * *
14 | * S E C U R E M O B I L E N E T W O R K I N G *
15 | * *
16 | * This file is part of NexMon. *
17 | * *
18 | * Based on: *
19 | * *
20 | * This code is based on the ldpreloadhook example by Pau Oliva Fora *
21 | * and the idea of hooking ioctls to fake a monitor mode *
22 | * interface, which was presented by Omri Ildis, Yuval Ofir and Ruby *
23 | * Feinstein at recon2013. *
24 | * *
25 | * Copyright (c) 2016 NexMon Team *
26 | * *
27 | * NexMon is free software: you can redistribute it and/or modify *
28 | * it under the terms of the GNU General Public License as published by *
29 | * the Free Software Foundation, either version 3 of the License, or *
30 | * (at your option) any later version. *
31 | * *
32 | * NexMon is distributed in the hope that it will be useful, *
33 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
34 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
35 | * GNU General Public License for more details. *
36 | * *
37 | * You should have received a copy of the GNU General Public License *
38 | * along with NexMon. If not, see . *
39 | * *
40 | **************************************************************************/
41 |
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 | #include
48 | #include
49 | #include
50 | #include
51 | #include
52 | #include
53 | #include
54 | #include
55 | #include
56 |
57 | #define CONFIG_LIBNL
58 |
59 | #ifdef CONFIG_LIBNL
60 | #include
61 | #include
62 | #include
63 | #include
64 | #include
65 | #include
66 | #include
67 | #endif // CONFIG_LIBNL
68 |
69 | #define __USE_POSIX199309
70 | #define _POSIX_C_SOURCE 199309L
71 | #include
72 |
73 | typedef unsigned int uint;
74 |
75 | #define TYPEDEF_BOOL // define this to make not throw an error trying to redefine bool
76 | #include
77 | #include
78 |
79 | #define WLC_GET_MONITOR 107
80 | #define WLC_SET_MONITOR 108
81 |
82 | struct nexio {
83 | struct ifreq *ifr;
84 | int sock_rx_ioctl;
85 | int sock_rx_frame;
86 | int sock_tx;
87 | };
88 |
89 | extern int nex_ioctl(struct nexio *nexio, int cmd, void *buf, int len, bool set);
90 | extern struct nexio *nex_init_ioctl(const char *ifname);
91 |
92 | #ifndef RTLD_NEXT
93 | #define RTLD_NEXT ((void *) -1l)
94 | #endif
95 |
96 | #define REAL_LIBC RTLD_NEXT
97 | #ifdef CONFIG_LIBNL
98 | #define REAL_LIBNL RTLD_NEXT
99 | #endif // CONFIG_LIBNL
100 |
101 | int frequency_to_channel(int);
102 | int nex_set_channel_simple(int);
103 | int nex_set_channel_full(uint32, uint32, uint32, uint32);
104 |
105 | typedef int request_t;
106 |
107 | typedef void (*sighandler_t)(int);
108 |
109 | static struct nexio *nexio = NULL;
110 |
111 | static const char *ifname = "wlan0";
112 |
113 | static int (*func_sendto) (int, const void *, size_t, int, const struct sockaddr *, socklen_t) = NULL;
114 | static int (*func_ioctl) (int, request_t, void *) = NULL;
115 | static int (*func_socket) (int, int, int) = NULL;
116 | static int (*func_bind) (int, const struct sockaddr *, int) = NULL;
117 | static int (*func_write) (int, const void *, size_t) = NULL;
118 | #ifdef CONFIG_LIBNL
119 | static int (*func_nl_send_auto_complete) (struct nl_sock *, struct nl_msg *) = NULL;
120 | #endif // CONFIG_LIBNL
121 |
122 | static void _libmexmon_init() __attribute__ ((constructor));
123 | static void _libmexmon_init() {
124 | nexio = nex_init_ioctl(ifname);
125 |
126 | if (! func_ioctl)
127 | func_ioctl = (int (*) (int, request_t, void *)) dlsym (REAL_LIBC, "ioctl");
128 |
129 | if (! func_socket)
130 | func_socket = (int (*) (int, int, int)) dlsym (REAL_LIBC, "socket");
131 |
132 | if (! func_bind)
133 | func_bind = (int (*) (int, const struct sockaddr *, int)) dlsym (REAL_LIBC, "bind");
134 |
135 | if (! func_write)
136 | func_write = (int (*) (int, const void *, size_t)) dlsym (REAL_LIBC, "write");
137 |
138 | if (! func_sendto)
139 | func_sendto = (int (*) (int, const void *, size_t, int, const struct sockaddr *, socklen_t)) dlsym (REAL_LIBC, "sendto");
140 |
141 | #ifdef CONFIG_LIBNL
142 | if (! func_nl_send_auto_complete)
143 | func_nl_send_auto_complete = (int (*) (struct nl_sock *, struct nl_msg *)) dlsym(REAL_LIBNL, "nl_send_auto_complete");
144 | #endif // CONFIG_LIBNL
145 | }
146 |
147 | #ifdef CONFIG_LIBNL
148 | static int _nl80211_type = 0;
149 | int nl80211_type()
150 | {
151 | if(_nl80211_type)
152 | {
153 | // fprintf(stderr, "cached\n");
154 | return _nl80211_type;
155 | }
156 |
157 | int rval;
158 | struct nl_sock *nl_sock = NULL;
159 | struct nl_cache *nl_cache = NULL;
160 | struct genl_family *nl80211 = NULL;
161 |
162 | // fprintf(stderr, "beginning\n");
163 | nl_sock = nl_socket_alloc();
164 | // fprintf(stderr, "nl_sock=%d\n", nl_sock);
165 | if(!nl_sock)
166 | return 0;
167 |
168 | rval = genl_connect(nl_sock);
169 | // fprintf(stderr, "genl_connect=%d\n", rval);
170 | if(rval)
171 | {
172 | nl_socket_free(nl_sock);
173 | return 0;
174 | }
175 |
176 | rval = genl_ctrl_alloc_cache(nl_sock, &nl_cache);
177 | // fprintf(stderr, "genl_ctrl_allocate_cache=%d\n", rval);
178 | if(rval)
179 | {
180 | nl_socket_free(nl_sock);
181 | return 0;
182 | }
183 |
184 | nl80211 = genl_ctrl_search_by_name(nl_cache, "nl80211");
185 | // fprintf(stderr, "genl_ctrl_search_by_name=%d\n", !!nl80211);
186 |
187 | if(nl80211)
188 | {
189 | _nl80211_type = genl_family_get_id(nl80211);
190 | // fprintf(stderr, "_nl80211_type=%d\n", _nl80211_type);
191 | }
192 |
193 | nl_cache_free(nl_cache);
194 | nl_socket_free(nl_sock);
195 | return _nl80211_type;
196 | }
197 |
198 | int handle_nl_msg(struct nl_msg *msg)
199 | {
200 | int retval;
201 | struct nlmsghdr *nlh;
202 | struct genlmsghdr *ghdr;
203 | struct nlattr *attr[NL80211_ATTR_MAX+1];
204 | struct nla_policy policy[4] = {
205 | [0] = { .type = NLA_U32 },
206 | };
207 |
208 | nlh = nlmsg_hdr(msg);
209 |
210 |
211 | // if this isn't an nl80211 message, we don't want it
212 | if(nlh->nlmsg_type != nl80211_type())
213 | return 0;
214 | if(nlmsg_get_proto(msg) != NETLINK_GENERIC)
215 | return 0;
216 |
217 | // fprintf(stderr, "nlmsg_parse\n");
218 | retval = nlmsg_parse(nlh, GENL_HDRLEN, attr, NL80211_ATTR_MAX, policy);
219 | // fprintf(stderr, "retval=%d\n", retval);
220 | if(retval)
221 | return 0;
222 |
223 | ghdr = nlmsg_data(nlh);
224 | if(ghdr->cmd == NL80211_CMD_SET_WIPHY)
225 | {
226 | int chan = 0;
227 | int ht_mode = NL80211_CHAN_HT20;
228 | int bandwidth = WL_CHANSPEC_BW_20;
229 | int band = WL_CHANSPEC_BAND_2G;
230 | int ctl_sb = 0;
231 |
232 | if(!attr[NL80211_ATTR_IFINDEX])
233 | return 0;
234 | if( nla_get_u32(attr[NL80211_ATTR_IFINDEX]) != if_nametoindex(ifname))
235 | return 0;
236 | // fprintf(stderr, "NL80211_ATTR_IFINDEX = %u\n", nla_get_u32(attr[NL80211_ATTR_IFINDEX]));
237 |
238 | if(attr[NL80211_ATTR_WIPHY_FREQ])
239 | {
240 | int freq = nla_get_u32(attr[NL80211_ATTR_WIPHY_FREQ]);
241 | chan = frequency_to_channel(freq);
242 | if(freq >= 5000)
243 | band = WL_CHANSPEC_BAND_5G;
244 | // fprintf(stderr, "NL80211_ATTR_WIPHY_FREQ = %u (%d)\n", freq, chan);
245 | }
246 | // HT20/HT40-/HT40+/... there are more but our device doesn't support that anyway
247 | if(attr[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
248 | {
249 | ht_mode = nla_get_u32(attr[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
250 | // fprintf(stderr, "NL80211_ATTR_WIPHY_CHANNEL_TYPE = %u\n", nla_get_u32(attr[NL80211_ATTR_WIPHY_CHANNEL_TYPE]));
251 | }
252 | if(attr[NL80211_ATTR_CHANNEL_WIDTH])
253 | {
254 | if(nla_get_u32(attr[NL80211_ATTR_CHANNEL_WIDTH]) == NL80211_CHAN_WIDTH_40)
255 | bandwidth = WL_CHANSPEC_BW_40;
256 | // fprintf(stderr, "NL80211_ATTR_CHANNEL_WIDTH = %u\n", nla_get_u32(attr[NL80211_ATTR_CHANNEL_WIDTH]));
257 | }
258 | if(attr[NL80211_ATTR_CENTER_FREQ1])
259 | {
260 | int freq = nla_get_u32(attr[NL80211_ATTR_CENTER_FREQ1]);
261 | int ctl_chan = frequency_to_channel(freq);
262 | if(ctl_chan > chan)
263 | ctl_sb = WL_CHANSPEC_CTL_SB_LLL;
264 | else if (ctl_chan < chan)
265 | ctl_sb = WL_CHANSPEC_CTL_SB_LLU;
266 | chan = ctl_chan;
267 | // fprintf(stderr, "NL80211_ATTR_CENTER_FREQ1 = %u\n", freq, frequency_to_channel(freq));
268 | }
269 | // this device doesn't support 80+80 anyway
270 | // if(attr[NL80211_ATTR_CENTER_FREQ2])
271 | // fprintf(stderr, "NL80211_ATTR_CENTER_FREQ2 = %u\n", nla_get_u32(attr[NL80211_ATTR_CENTER_FREQ2]));
272 |
273 | if(ht_mode == NL80211_CHAN_HT40PLUS)
274 | {
275 | if(band == WL_CHANSPEC_BAND_2G)
276 | {
277 | bandwidth = WL_CHANSPEC_BW_40;
278 | chan = LOWER_20_SB(chan);
279 | ctl_sb = WL_CHANSPEC_CTL_SB_LLU;
280 | }
281 | else
282 | ht_mode = NL80211_CHAN_HT40MINUS; // there is only one sideband allowed for 40MHz in 5G band
283 | }
284 | if(ht_mode == NL80211_CHAN_HT40MINUS)
285 | {
286 | bandwidth = WL_CHANSPEC_BW_40;
287 | chan = UPPER_20_SB(chan);
288 | ctl_sb = WL_CHANSPEC_CTL_SB_LLL;
289 | }
290 |
291 | if(chan)
292 | // nex_set_channel_simple(chan);
293 | return nex_set_channel_full(chan, band, bandwidth, ctl_sb);
294 |
295 | }
296 | if(ghdr->cmd == NL80211_CMD_SET_INTERFACE)
297 | {
298 | if(!attr[NL80211_ATTR_IFINDEX])
299 | return 0;
300 | if( nla_get_u32(attr[NL80211_ATTR_IFINDEX]) != if_nametoindex(ifname))
301 | return 0;
302 | // fprintf(stderr, "NL80211_ATTR_IFINDEX = %u\n", nla_get_u32(attr[NL80211_ATTR_IFINDEX]));
303 |
304 | // we could set monitor/managed mode based on this message
305 | if(attr[NL80211_ATTR_IFTYPE])
306 | {
307 | // fprintf(stderr, "NL80211_ATTR_IFTYPE = %u\n", nla_get_u32(attr[NL80211_ATTR_IFTYPE]));
308 | }
309 | }
310 |
311 | return 0;
312 | }
313 |
314 | // there are several other functions that can send netlink messages, but it looks like airodump-ng and kismet both use this one, so this is good enough for now
315 | int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
316 | {
317 | int ret;
318 |
319 | ret = func_nl_send_auto_complete(sk, msg);
320 |
321 | // fprintf(stderr, "\nnl_send_auto_complete()\n");
322 | ret = handle_nl_msg(msg);
323 | return ret;
324 | }
325 | #endif // CONFIG_LIBNL
326 |
327 | int frequency_to_channel(int freq_in_MHz)
328 | {
329 | if(freq_in_MHz == 2484)
330 | return 14;
331 | if(freq_in_MHz >= 2412 && freq_in_MHz <= 2472)
332 | return (freq_in_MHz-2407)/5;
333 | if(freq_in_MHz >= 5000 && freq_in_MHz <= 6000)
334 | return (freq_in_MHz-5000)/5;
335 |
336 | return 0;
337 | }
338 |
339 | int nex_set_channel_simple(int channel)
340 | {
341 | int band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
342 | return nex_set_channel_full(channel, band, WL_CHANSPEC_BW_20, 0);
343 | }
344 |
345 | int nex_set_channel_full(uint32 channel, uint32 band, uint32 bw, uint32 ctl_sb)
346 | {
347 | char charbuf[13] = "chanspec";
348 | uint32 *chanspec = (uint32*) &charbuf[9];
349 |
350 | *chanspec = (channel | band | bw | ctl_sb);
351 | // fprintf(stderr, "setting channel: channel=%08x band=%08x bw=%08x ctl_sb=%08x chanspec=%08x\n", channel, band, bw, ctl_sb, *chanspec);
352 | return nex_ioctl(nexio, WLC_SET_VAR, charbuf, 13, true);
353 | }
354 |
355 | int
356 | ioctl(int fd, request_t request, ...)
357 | {
358 | va_list args;
359 | void *argp;
360 | int ret;
361 |
362 | va_start (args, request);
363 | argp = va_arg (args, void *);
364 | va_end (args);
365 |
366 | ret = func_ioctl(fd, request, argp);
367 | //if (ret < 0) {
368 | // fprintf(stderr, "LIBNEXMON: original response: %d, request: 0x%x\n", ret, request);
369 | //}
370 |
371 | switch (request) {
372 | case SIOCGIFHWADDR:
373 | {
374 | int buf;
375 | struct ifreq* p_ifr = (struct ifreq *) argp;
376 | if (!strncmp(p_ifr->ifr_ifrn.ifrn_name, ifname, strlen(ifname))) {
377 | nex_ioctl(nexio, WLC_GET_MONITOR, &buf, 4, false);
378 |
379 | if (buf & MONITOR_IEEE80211) p_ifr->ifr_hwaddr.sa_family = ARPHRD_IEEE80211;
380 | else if (buf & MONITOR_RADIOTAP) p_ifr->ifr_hwaddr.sa_family = ARPHRD_IEEE80211_RADIOTAP;
381 | else if (buf & MONITOR_DISABLED || buf & MONITOR_LOG_ONLY || buf & MONITOR_DROP_FRM || buf & MONITOR_IPV4_UDP)
382 | p_ifr->ifr_hwaddr.sa_family = ARPHRD_ETHER;
383 |
384 | ret = 0;
385 | }
386 | }
387 | break;
388 |
389 | case SIOCGIWMODE:
390 | {
391 | int buf;
392 | struct iwreq* p_wrq = (struct iwreq*) argp;
393 |
394 | if (!strncmp(p_wrq->ifr_ifrn.ifrn_name, ifname, strlen(ifname))) {
395 | nex_ioctl(nexio, WLC_GET_MONITOR, &buf, 4, false);
396 |
397 | if (buf & MONITOR_RADIOTAP || buf & MONITOR_IEEE80211 || buf & MONITOR_LOG_ONLY || buf & MONITOR_DROP_FRM || buf & MONITOR_IPV4_UDP) {
398 | p_wrq->u.mode = IW_MODE_MONITOR;
399 | }
400 |
401 | ret = 0;
402 | }
403 | }
404 | break;
405 |
406 | case SIOCSIWMODE:
407 | {
408 | int buf;
409 | struct iwreq* p_wrq = (struct iwreq*) argp;
410 |
411 | if (!strncmp(p_wrq->ifr_ifrn.ifrn_name, ifname, strlen(ifname))) {
412 | if (p_wrq->u.mode == IW_MODE_MONITOR) {
413 | buf = MONITOR_RADIOTAP;
414 | } else {
415 | buf = MONITOR_DISABLED;
416 | }
417 |
418 | ret = nex_ioctl(nexio, WLC_SET_MONITOR, &buf, 4, true);
419 | }
420 | }
421 | break;
422 |
423 | case SIOCSIWFREQ: // set channel/frequency (Hz)
424 | {
425 | struct iwreq* p_wrq = (struct iwreq*) argp;
426 |
427 | if (!strncmp(p_wrq->ifr_ifrn.ifrn_name, ifname, strlen(ifname))) {
428 | char charbuf[13] = "chanspec";
429 | uint32 *chanspec = (uint32*) &charbuf[9];
430 | int channel = p_wrq->u.freq.m;
431 | int exp = p_wrq->u.freq.e;
432 |
433 | // TODO: test this!
434 | // fprintf(stderr, "SIWFREQ: chan/freq: m=%d e=%d\n", channel, exp);
435 | // if this is > 500 (or 1000, depending on the source), it's a frequency, not a channel
436 | if(channel > 500 || exp > 0)
437 | {
438 | // convert from Hz to MHz
439 | if(exp < 6)
440 | {
441 | for(int i=0;iifr_ifrn.ifrn_name, ifname, strlen(ifname))) {
469 | char charbuf[9] = "chanspec";
470 | uint16 chanspec;
471 | int32 channel;
472 | ret = nex_ioctl(nexio, WLC_GET_VAR, charbuf, 9, false);
473 | if(ret >= 0) {
474 | chanspec = *(uint16 *) charbuf;
475 | channel = chanspec & 0xFF;
476 | p_wrq->u.freq.e = 0;
477 | p_wrq->u.freq.m = channel;
478 | // fprintf(stderr, "GIWFREQ: channel=%d\n", channel);
479 | }
480 |
481 | }
482 |
483 |
484 | //if (ret < 0)
485 | //fprintf(stderr, "LIBNEXMON: SIOCGIWFREQ not fully implemented\n");
486 | }
487 | break;
488 | }
489 | return ret;
490 | }
491 |
492 | void
493 | hexdump(const char *desc, const void *addr, int len)
494 | {
495 | int i;
496 | unsigned char buff[17];
497 | unsigned char *pc = (unsigned char*)addr;
498 |
499 | // Output description if given.
500 | if (desc != 0)
501 | printf ("%s:\n", desc);
502 |
503 | // Process every byte in the data.
504 | for (i = 0; i < len; i++) {
505 | // Multiple of 16 means new line (with line offset).
506 |
507 | if ((i % 16) == 0) {
508 | // Just don't print ASCII for the zeroth line.
509 | if (i != 0)
510 | printf (" %s\n", buff);
511 |
512 | // Output the offset.
513 | printf (" %04x ", i);
514 | }
515 |
516 | // Now the hex code for the specific character.
517 | printf (" %02x", pc[i]);
518 |
519 | // And store a printable ASCII character for later.
520 | if ((pc[i] < 0x20) || (pc[i] > 0x7e))
521 | buff[i % 16] = '.';
522 | else
523 | buff[i % 16] = pc[i];
524 | buff[(i % 16) + 1] = '\0';
525 | }
526 |
527 | // Pad out last line if not exactly 16 characters.
528 | while ((i % 16) != 0) {
529 | printf (" ");
530 | i++;
531 | }
532 |
533 | // And print the final ASCII bit.
534 | printf (" %s\n", buff);
535 | }
536 |
537 | static char sock_types[][16] = {
538 | "SOCK_STREAM",
539 | "SOCK_DGRAM",
540 | "SOCK_RAW",
541 | "SOCK_RDM",
542 | "SOCK_SEQPACKET",
543 | };
544 |
545 | static char domain_types[][16] = {
546 | "AF_UNSPEC",
547 | "AF_UNIX",
548 | "AF_INET",
549 | "AF_AX25",
550 | "AF_IPX",
551 | "AF_APPLETALK",
552 | "AF_NETROM",
553 | "AF_BRIDGE",
554 | "AF_ATMPVC",
555 | "AF_X25",
556 | "AF_INET6",
557 | "AF_ROSE",
558 | "AF_DECnet",
559 | "AF_NETBEUI",
560 | "AF_SECURITY",
561 | "AF_KEY",
562 | "AF_NETLINK",
563 | "AF_PACKET",
564 | "AF_ASH",
565 | "AF_ECONET",
566 | "AF_ATMSVC",
567 | "AF_RDS",
568 | "AF_SNA",
569 | "AF_IRDA",
570 | "AF_PPPOX",
571 | "AF_WANPIPE",
572 | "AF_LLC",
573 | "AF_IB",
574 | "AF_MPLS",
575 | "AF_CAN",
576 | "AF_TIPC",
577 | "AF_BLUETOOTH",
578 | "AF_IUCV",
579 | "AF_RXRPC",
580 | "AF_ISDN",
581 | "AF_PHONET",
582 | "AF_IEEE802154",
583 | "AF_CAIF",
584 | "AF_ALG",
585 | "AF_NFC",
586 | "AF_VSOCK",
587 | "AF_KCM",
588 | "AF_QIPCRTR",
589 | "AF_SMC"
590 | };
591 |
592 | int socket_to_type[100] = { 0 };
593 | char bound_to_correct_if[100] = { 0 };
594 |
595 | int
596 | socket(int domain, int type, int protocol)
597 | {
598 | int ret;
599 |
600 | ret = func_socket(domain, type, protocol);
601 |
602 | // save the socket type
603 | if (ret < sizeof(socket_to_type)/sizeof(socket_to_type[0]))
604 | socket_to_type[ret] = type;
605 |
606 | //if ((type - 1 < sizeof(sock_types)/sizeof(sock_types[0])) && (domain - 1 < sizeof(domain_types)/sizeof(domain_types[0])))
607 | // printf("LIBNEXMON: %d = %s(%s(%d), %s(%d), %d)\n", ret, __FUNCTION__, domain_types[domain], domain, sock_types[type - 1], type, protocol);
608 |
609 | return ret;
610 | }
611 |
612 | int
613 | bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
614 | {
615 | int ret;
616 | struct sockaddr_ll *sll = (struct sockaddr_ll *) addr;
617 |
618 | ret = func_bind(sockfd, addr, addrlen);
619 |
620 | char sll_ifname[IF_NAMESIZE] = { 0 };
621 | if_indextoname(sll->sll_ifindex, sll_ifname);
622 |
623 | if ((sockfd < sizeof(bound_to_correct_if)/sizeof(bound_to_correct_if[0])) && !strncmp(ifname, sll_ifname, sizeof(ifname)))
624 | bound_to_correct_if[sockfd] = 1;
625 |
626 | //printf("LIBNEXMON: %d = %s(%d, 0x%p, %d) sll_ifindex=%d ifname=%s\n", ret, __FUNCTION__, sockfd, addr, addrlen, sll->sll_ifindex, sll_ifname);
627 |
628 | return ret;
629 | }
630 |
631 | struct inject_frame {
632 | unsigned short len;
633 | unsigned char pad;
634 | unsigned char type;
635 | char data[];
636 | };
637 |
638 | ssize_t
639 | write(int fd, const void *buf, size_t count)
640 | {
641 | ssize_t ret;
642 |
643 | // check if the user wants to write on a raw socket
644 | if ((fd > 2) && (fd < sizeof(socket_to_type)/sizeof(socket_to_type[0])) && (socket_to_type[fd] == SOCK_RAW) && (bound_to_correct_if[fd] == 1)) {
645 | struct inject_frame *buf_dup = (struct inject_frame *) malloc(count + sizeof(struct inject_frame));
646 |
647 | buf_dup->len = count + sizeof(struct inject_frame);
648 | buf_dup->pad = 0;
649 | buf_dup->type = 1;
650 | memcpy(buf_dup->data, buf, count);
651 |
652 | // fprintf(stderr, "injecting!\n");
653 | nex_ioctl(nexio, NEX_INJECT_FRAME, buf_dup, count + sizeof(struct inject_frame), true);
654 | free(buf_dup);
655 |
656 | // this is probably frowned on, but it works on the Nexus 6P
657 | // rate-limiting keeps the driver from crashing when doing aireplay-ng
658 | struct timespec ts;
659 | ts.tv_sec = 0;
660 | ts.tv_nsec = 50 * 1000000; // 50 ms
661 | nanosleep(&ts, NULL);
662 |
663 | ret = count;
664 | } else {
665 | // otherwise write the regular frame to the socket
666 | ret = func_write(fd, buf, count);
667 | }
668 |
669 | return ret;
670 | }
671 |
672 | ssize_t
673 | sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
674 | {
675 | ssize_t ret;
676 |
677 | // check if the user wants to write on a raw socket
678 | if ((sockfd > 2) && (sockfd < sizeof(socket_to_type)/sizeof(socket_to_type[0])) && (socket_to_type[sockfd] == SOCK_RAW) && (bound_to_correct_if[sockfd] == 1)) {
679 | struct inject_frame *buf_dup = (struct inject_frame *) malloc(len + sizeof(struct inject_frame));
680 |
681 | buf_dup->len = len + sizeof(struct inject_frame);
682 | buf_dup->pad = 0;
683 | buf_dup->type = 1;
684 | memcpy(buf_dup->data, buf, len);
685 |
686 | nex_ioctl(nexio, NEX_INJECT_FRAME, buf_dup, len + sizeof(struct inject_frame), true);
687 |
688 | free(buf_dup);
689 |
690 | ret = len;
691 | } else {
692 | // otherwise write the regular frame to the socket
693 | ret = func_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
694 | }
695 |
696 | return ret;
697 | }
698 |
--------------------------------------------------------------------------------
/typedefs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 1999-2013, Broadcom Corporation
3 | *
4 | * Unless you and Broadcom execute a separate written software license
5 | * agreement governing use of this software, this software is licensed to you
6 | * under the terms of the GNU General Public License version 2 (the "GPL"),
7 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the
8 | * following added to such license:
9 | *
10 | * As a special exception, the copyright holders of this software give you
11 | * permission to link this software with independent modules, and to copy and
12 | * distribute the resulting executable under terms of your choice, provided that
13 | * you also meet, for each linked independent module, the terms and conditions of
14 | * the license of that module. An independent module is a module which is not
15 | * derived from this software. The special exception does not apply to any
16 | * modifications of the software.
17 | *
18 | * Notwithstanding the above, under no circumstances may you combine this
19 | * software in any way with any other Broadcom software provided under a license
20 | * other than the GPL, without Broadcom's express prior written consent.
21 | * $Id: typedefs.h 397286 2013-04-18 01:42:19Z $
22 | */
23 |
24 | #ifndef _TYPEDEFS_H_
25 | #define _TYPEDEFS_H_
26 |
27 | #ifdef SITE_TYPEDEFS
28 |
29 | /*
30 | * Define SITE_TYPEDEFS in the compile to include a site-specific
31 | * typedef file "site_typedefs.h".
32 | *
33 | * If SITE_TYPEDEFS is not defined, then the code section below makes
34 | * inferences about the compile environment based on defined symbols and
35 | * possibly compiler pragmas.
36 | *
37 | * Following these two sections is the Default Typedefs section.
38 | * This section is only processed if USE_TYPEDEF_DEFAULTS is
39 | * defined. This section has a default set of typedefs and a few
40 | * preprocessor symbols (TRUE, FALSE, NULL, ...).
41 | */
42 |
43 | #include "site_typedefs.h"
44 |
45 | #else
46 |
47 | /*
48 | * Infer the compile environment based on preprocessor symbols and pragmas.
49 | * Override type definitions as needed, and include configuration-dependent
50 | * header files to define types.
51 | */
52 |
53 | #ifdef __cplusplus
54 |
55 | #define TYPEDEF_BOOL
56 | #ifndef FALSE
57 | #define FALSE false
58 | #endif
59 | #ifndef TRUE
60 | #define TRUE true
61 | #endif
62 |
63 | #else /* ! __cplusplus */
64 |
65 |
66 | #endif /* ! __cplusplus */
67 |
68 | #if defined(__x86_64__)
69 | #define TYPEDEF_UINTPTR
70 | typedef unsigned long long int uintptr;
71 | #endif
72 |
73 |
74 |
75 |
76 |
77 | #if defined(_NEED_SIZE_T_)
78 | typedef long unsigned int size_t;
79 | #endif
80 |
81 |
82 |
83 |
84 |
85 | #if defined(__sparc__)
86 | #define TYPEDEF_ULONG
87 | #endif
88 |
89 |
90 | /*
91 | * If this is either a Linux hybrid build or the per-port code of a hybrid build
92 | * then use the Linux header files to get some of the typedefs. Otherwise, define
93 | * them entirely in this file. We can't always define the types because we get
94 | * a duplicate typedef error; there is no way to "undefine" a typedef.
95 | * We know when it's per-port code because each file defines LINUX_PORT at the top.
96 | */
97 | #if !defined(LINUX_HYBRID) || defined(LINUX_PORT)
98 | #define TYPEDEF_UINT
99 | #ifndef TARGETENV_android
100 | #define TYPEDEF_USHORT
101 | #define TYPEDEF_ULONG
102 | #endif /* TARGETENV_android */
103 | #ifdef __KERNEL__
104 | #include
105 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19))
106 | #define TYPEDEF_BOOL
107 | #endif /* >= 2.6.19 */
108 | /* special detection for 2.6.18-128.7.1.0.1.el5 */
109 | #if (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18))
110 | #include
111 | #ifdef noinline_for_stack
112 | #define TYPEDEF_BOOL
113 | #endif
114 | #endif /* == 2.6.18 */
115 | #endif /* __KERNEL__ */
116 | #endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */
117 |
118 |
119 |
120 |
121 | /* Do not support the (u)int64 types with strict ansi for GNU C */
122 | #if defined(__GNUC__) && defined(__STRICT_ANSI__)
123 | #define TYPEDEF_INT64
124 | #define TYPEDEF_UINT64
125 | #endif /* defined(__GNUC__) && defined(__STRICT_ANSI__) */
126 |
127 | /* ICL accepts unsigned 64 bit type only, and complains in ANSI mode
128 | * for signed or unsigned
129 | */
130 | #if defined(__ICL)
131 |
132 | #define TYPEDEF_INT64
133 |
134 | #if defined(__STDC__)
135 | #define TYPEDEF_UINT64
136 | #endif
137 |
138 | #endif /* __ICL */
139 |
140 | #if !defined(__DJGPP__)
141 |
142 | /* pick up ushort & uint from standard types.h */
143 | #if defined(__KERNEL__)
144 |
145 | /* See note above */
146 | #if !defined(LINUX_HYBRID) || defined(LINUX_PORT)
147 | #include /* sys/types.h and linux/types.h are oil and water */
148 | #endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */
149 |
150 | #else
151 |
152 |
153 | #include
154 |
155 | #endif /* linux && __KERNEL__ */
156 |
157 | #endif
158 |
159 |
160 |
161 | /* use the default typedefs in the next section of this file */
162 | #define USE_TYPEDEF_DEFAULTS
163 |
164 | #endif /* SITE_TYPEDEFS */
165 |
166 |
167 | /*
168 | * Default Typedefs
169 | */
170 |
171 | #ifdef USE_TYPEDEF_DEFAULTS
172 | #undef USE_TYPEDEF_DEFAULTS
173 |
174 | #ifndef TYPEDEF_BOOL
175 | typedef /* @abstract@ */ unsigned char bool;
176 | #endif
177 |
178 | /* define uchar, ushort, uint, ulong */
179 |
180 | #ifndef TYPEDEF_UCHAR
181 | typedef unsigned char uchar;
182 | #endif
183 |
184 | #ifndef TYPEDEF_USHORT
185 | typedef unsigned short ushort;
186 | #endif
187 |
188 | #ifndef TYPEDEF_UINT
189 | typedef unsigned int uint;
190 | #endif
191 |
192 | #ifndef TYPEDEF_ULONG
193 | typedef unsigned long ulong;
194 | #endif
195 |
196 | /* define [u]int8/16/32/64, uintptr */
197 |
198 | #ifndef TYPEDEF_UINT8
199 | typedef unsigned char uint8;
200 | #endif
201 |
202 | #ifndef TYPEDEF_UINT16
203 | typedef unsigned short uint16;
204 | #endif
205 |
206 | #ifndef TYPEDEF_UINT32
207 | typedef unsigned int uint32;
208 | #endif
209 |
210 | #ifndef TYPEDEF_UINT64
211 | typedef unsigned long long uint64;
212 | #endif
213 |
214 | #ifndef TYPEDEF_UINTPTR
215 | typedef unsigned int uintptr;
216 | #endif
217 |
218 | #ifndef TYPEDEF_INT8
219 | typedef signed char int8;
220 | #endif
221 |
222 | #ifndef TYPEDEF_INT16
223 | typedef signed short int16;
224 | #endif
225 |
226 | #ifndef TYPEDEF_INT32
227 | typedef signed int int32;
228 | #endif
229 |
230 | #ifndef TYPEDEF_INT64
231 | typedef signed long long int64;
232 | #endif
233 |
234 | /* define float32/64, float_t */
235 |
236 | #ifndef TYPEDEF_FLOAT32
237 | typedef float float32;
238 | #endif
239 |
240 | #ifndef TYPEDEF_FLOAT64
241 | typedef double float64;
242 | #endif
243 |
244 | /*
245 | * abstracted floating point type allows for compile time selection of
246 | * single or double precision arithmetic. Compiling with -DFLOAT32
247 | * selects single precision; the default is double precision.
248 | */
249 |
250 | #ifndef TYPEDEF_FLOAT_T
251 |
252 | #if defined(FLOAT32)
253 | typedef float32 float_t;
254 | #else /* default to double precision floating point */
255 | typedef float64 float_t;
256 | #endif
257 |
258 | #endif /* TYPEDEF_FLOAT_T */
259 |
260 | /* define macro values */
261 |
262 | #ifndef FALSE
263 | #define FALSE 0
264 | #endif
265 |
266 | #ifndef TRUE
267 | #define TRUE 1 /* TRUE */
268 | #endif
269 |
270 | #ifndef NULL
271 | #define NULL 0
272 | #endif
273 |
274 | #ifndef OFF
275 | #define OFF 0
276 | #endif
277 |
278 | #ifndef ON
279 | #define ON 1 /* ON = 1 */
280 | #endif
281 |
282 | #define AUTO (-1) /* Auto = -1 */
283 |
284 | /* define PTRSZ, INLINE */
285 |
286 | #ifndef PTRSZ
287 | #define PTRSZ sizeof(char*)
288 | #endif
289 |
290 |
291 | /* Detect compiler type. */
292 | #if defined(__GNUC__) || defined(__lint)
293 | #define BWL_COMPILER_GNU
294 | #elif defined(__CC_ARM) && __CC_ARM
295 | #define BWL_COMPILER_ARMCC
296 | #else
297 | #error "Unknown compiler!"
298 | #endif
299 |
300 |
301 | #ifndef INLINE
302 | #if defined(BWL_COMPILER_MICROSOFT)
303 | #define INLINE __inline
304 | #elif defined(BWL_COMPILER_GNU)
305 | #define INLINE __inline__
306 | #elif defined(BWL_COMPILER_ARMCC)
307 | #define INLINE __inline
308 | #else
309 | #define INLINE
310 | #endif
311 | #endif /* INLINE */
312 |
313 | #undef TYPEDEF_BOOL
314 | #undef TYPEDEF_UCHAR
315 | #undef TYPEDEF_USHORT
316 | #undef TYPEDEF_UINT
317 | #undef TYPEDEF_ULONG
318 | #undef TYPEDEF_UINT8
319 | #undef TYPEDEF_UINT16
320 | #undef TYPEDEF_UINT32
321 | #undef TYPEDEF_UINT64
322 | #undef TYPEDEF_UINTPTR
323 | #undef TYPEDEF_INT8
324 | #undef TYPEDEF_INT16
325 | #undef TYPEDEF_INT32
326 | #undef TYPEDEF_INT64
327 | #undef TYPEDEF_FLOAT32
328 | #undef TYPEDEF_FLOAT64
329 | #undef TYPEDEF_FLOAT_T
330 |
331 | #endif /* USE_TYPEDEF_DEFAULTS */
332 |
333 | /* Suppress unused parameter warning */
334 | #define UNUSED_PARAMETER(x) (void)(x)
335 |
336 | /* Avoid warning for discarded const or volatile qualifier in special cases (-Wcast-qual) */
337 | #define DISCARD_QUAL(ptr, type) ((type *)(uintptr)(ptr))
338 |
339 | /*
340 | * Including the bcmdefs.h here, to make sure everyone including typedefs.h
341 | * gets this automatically
342 | */
343 | #include
344 | #endif /* _TYPEDEFS_H_ */
345 |
--------------------------------------------------------------------------------