xref: /openbsd/usr.sbin/hostapd/hostapd.h (revision b9fc9a72)
1 /*	$OpenBSD: hostapd.h,v 1.21 2015/01/16 06:40:17 deraadt Exp $	*/
2 
3 /*
4  * Copyright (c) 2004, 2005 Reyk Floeter <reyk@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef _HOSTAPD_H
20 #define _HOSTAPD_H
21 
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/tree.h>
25 
26 #include <net/if.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
29 
30 #include <errno.h>
31 #include <event.h>
32 #include <syslog.h>
33 
34 #include <net80211/ieee80211.h>
35 #include <net80211/ieee80211_ioctl.h>
36 
37 /*
38  * hostapd (IAPP) <-> Host AP (APME)
39  */
40 
41 struct hostapd_node {
42 	u_int8_t	ni_macaddr[IEEE80211_ADDR_LEN];
43 	u_int8_t	ni_bssid[IEEE80211_ADDR_LEN];
44 	u_int32_t	ni_associd;
45 	u_int16_t	ni_capinfo;
46 	u_int16_t	ni_flags;
47 	u_int16_t	ni_rxseq;
48 	u_int16_t	ni_rssi;
49 };
50 
51 /*
52  * IAPP -> switches (LLC)
53  */
54 
55 struct hostapd_llc {
56 	struct ether_header x_hdr;
57 	struct llc x_llc;
58 } __packed;
59 
60 #define IAPP_LLC	LLC_XID
61 #define IAPP_LLC_XID	0x81
62 #define IAPP_LLC_CLASS	1
63 #define IAPP_LLC_WINDOW	1 << 1
64 
65 /*
66  * hostapd configuration
67  */
68 
69 struct hostapd_counter {
70 	u_int64_t	cn_tx_llc;	/* sent LLC messages */
71 	u_int64_t	cn_rx_iapp;	/* received IAPP messages */
72 	u_int64_t	cn_tx_iapp;	/* sent IAPP messages */
73 	u_int64_t	cn_rx_apme;	/* received Host AP messages */
74 	u_int64_t	cn_tx_apme;	/* sent Host AP messages */
75 	u_int64_t	cn_rtap_miss;	/* missing radiotap field */
76 };
77 
78 #define HOSTAPD_ENTRY_MASK_ADD(_a, _m)	do {					\
79 	(_a)[0] &= (_m)[0];							\
80 	(_a)[1] &= (_m)[1];							\
81 	(_a)[2] &= (_m)[2];							\
82 	(_a)[3] &= (_m)[3];							\
83 	(_a)[4] &= (_m)[4];							\
84 	(_a)[5] &= (_m)[5];							\
85 } while (0);
86 #define HOSTAPD_ENTRY_MASK_MATCH(_e, _b)	(				\
87 	((_e)->e_lladdr[0] == ((_b)[0] & (_e)->e_addr.a_mask[0])) &&		\
88 	((_e)->e_lladdr[1] == ((_b)[1] & (_e)->e_addr.a_mask[1])) &&		\
89 	((_e)->e_lladdr[2] == ((_b)[2] & (_e)->e_addr.a_mask[2])) &&		\
90 	((_e)->e_lladdr[3] == ((_b)[3] & (_e)->e_addr.a_mask[3])) &&		\
91 	((_e)->e_lladdr[4] == ((_b)[4] & (_e)->e_addr.a_mask[4])) &&		\
92 	((_e)->e_lladdr[5] == ((_b)[5] & (_e)->e_addr.a_mask[5]))		\
93 )
94 
95 struct hostapd_inaddr {
96 	sa_family_t		in_af;
97 	union {
98 		struct in_addr	v4;
99 		struct in6_addr	v6;
100 	} in_v;
101 	int			in_netmask;
102 };
103 
104 #define in_v4			in_v.v4
105 #define in_v6			in_v.v6
106 
107 struct hostapd_entry {
108 	u_int8_t			e_lladdr[IEEE80211_ADDR_LEN];
109 	u_int8_t			e_flags;
110 
111 #define HOSTAPD_ENTRY_F_LLADDR		0x00
112 #define HOSTAPD_ENTRY_F_MASK		0x01
113 #define HOSTAPD_ENTRY_F_INADDR		0x02
114 
115 	union {
116 		u_int8_t		a_mask[IEEE80211_ADDR_LEN];
117 		struct hostapd_inaddr	a_inaddr;
118 	}				e_addr;
119 
120 	RB_ENTRY(hostapd_entry)		e_nodes;
121 	TAILQ_ENTRY(hostapd_entry)	e_entries;
122 };
123 
124 #define e_mask				e_addr.a_mask
125 #define e_inaddr			e_addr.a_inaddr
126 
127 #define HOSTAPD_TABLE_NAMELEN		32
128 
129 RB_HEAD(hostapd_tree, hostapd_entry);
130 
131 struct hostapd_table {
132 	char				t_name[HOSTAPD_TABLE_NAMELEN];
133 	u_int8_t			t_flags;
134 
135 #define HOSTAPD_TABLE_F_CONST		0x01
136 
137 	struct hostapd_tree		t_tree;
138 	TAILQ_HEAD(, hostapd_entry)	t_mask_head;
139 	TAILQ_ENTRY(hostapd_table)	t_entries;
140 };
141 
142 struct hostapd_radiotap {
143 	u_int32_t	r_present;
144 	u_int8_t	r_txrate;
145 	u_int16_t	r_chan;
146 	u_int16_t	r_chan_flags;
147 	u_int8_t	r_rssi;
148 	u_int8_t	r_max_rssi;
149 };
150 #define HOSTAPD_RADIOTAP_F(_x)	(1 << IEEE80211_RADIOTAP_##_x)
151 
152 struct hostapd_ieee80211_frame {
153 	u_int8_t	i_fc[2];
154 	u_int8_t	i_dur[2];
155 	u_int8_t	i_from[IEEE80211_ADDR_LEN];
156 	u_int8_t	i_to[IEEE80211_ADDR_LEN];
157 	u_int8_t	i_bssid[IEEE80211_ADDR_LEN];
158 	u_int8_t	i_seq[2];
159 	void		*i_data;
160 	u_int		i_data_len;
161 };
162 
163 enum hostapd_action {
164 	HOSTAPD_ACTION_NONE	= 0,
165 	HOSTAPD_ACTION_LOG	= 1,
166 	HOSTAPD_ACTION_RADIOTAP	= 2,
167 	HOSTAPD_ACTION_FRAME	= 3,
168 	HOSTAPD_ACTION_ADDNODE	= 4,
169 	HOSTAPD_ACTION_DELNODE	= 5,
170 	HOSTAPD_ACTION_RESEND	= 6
171 };
172 
173 enum hostapd_op {
174 	HOSTAPD_OP_EQ		= 0,
175 	HOSTAPD_OP_NE		= 1,
176 	HOSTAPD_OP_LE		= 2,
177 	HOSTAPD_OP_LT		= 3,
178 	HOSTAPD_OP_GE		= 4,
179 	HOSTAPD_OP_GT		= 5
180 };
181 
182 struct hostapd_action_data {
183 	union {
184 		struct hostapd_ieee80211_frame	u_frame;
185 		u_int8_t			u_lladdr[IEEE80211_ADDR_LEN];
186 	} a_data;
187 	u_int16_t				a_flags;
188 
189 #define HOSTAPD_ACTION_F_REF_FROM		0x0001
190 #define HOSTAPD_ACTION_F_REF_TO			0x0002
191 #define HOSTAPD_ACTION_F_REF_BSSID		0x0004
192 #define HOSTAPD_ACTION_F_REF_RANDOM		0x0008
193 #define HOSTAPD_ACTION_F_REF_FROM_M		0x000f
194 #define HOSTAPD_ACTION_F_REF_FROM_S		0
195 #define HOSTAPD_ACTION_F_REF_TO_M		0x00f0
196 #define HOSTAPD_ACTION_F_REF_TO_S		4
197 #define HOSTAPD_ACTION_F_REF_BSSID_M		0x0f00
198 #define HOSTAPD_ACTION_F_REF_BSSID_S		8
199 #define HOSTAPD_ACTION_F_REF_M			0x0fff
200 #define HOSTAPD_ACTION_F_OPT_DIR_AUTO		0x1000
201 #define HOSTAPD_ACTION_F_OPT_LLADDR		0x2000
202 #define HOSTAPD_ACTION_F_OPT_TABLE		0x4000
203 };
204 
205 #define a_frame					a_data.u_frame
206 #define a_lladdr				a_data.u_lladdr
207 
208 struct hostapd_frame {
209 	struct hostapd_ieee80211_frame	f_frame;
210 	u_int32_t			f_radiotap;
211 
212 	u_int32_t			f_flags;
213 
214 #define HOSTAPD_FRAME_F_TYPE		0x00000001
215 #define HOSTAPD_FRAME_F_TYPE_N		0x00000002
216 #define HOSTAPD_FRAME_F_SUBTYPE		0x00000004
217 #define HOSTAPD_FRAME_F_SUBTYPE_N	0x00000008
218 #define HOSTAPD_FRAME_F_DIR		0x00000010
219 #define HOSTAPD_FRAME_F_DIR_N		0x00000020
220 #define HOSTAPD_FRAME_F_FROM		0x00000040
221 #define HOSTAPD_FRAME_F_FROM_N		0x00000080
222 #define HOSTAPD_FRAME_F_FROM_TABLE	0x00000100
223 #define HOSTAPD_FRAME_F_FROM_M		0x000001c0
224 #define HOSTAPD_FRAME_F_TO		0x00000200
225 #define HOSTAPD_FRAME_F_TO_N		0x00000400
226 #define HOSTAPD_FRAME_F_TO_TABLE	0x00000800
227 #define HOSTAPD_FRAME_F_TO_M		0x00000e00
228 #define HOSTAPD_FRAME_F_BSSID		0x00001000
229 #define HOSTAPD_FRAME_F_BSSID_N		0x00002000
230 #define HOSTAPD_FRAME_F_BSSID_TABLE	0x00004000
231 #define HOSTAPD_FRAME_F_BSSID_M		0x00007000
232 #define HOSTAPD_FRAME_F_APME		0x00008000
233 #define HOSTAPD_FRAME_F_APME_N		0x00010000
234 #define HOSTAPD_FRAME_F_APME_M		0x00018000
235 #define HOSTAPD_FRAME_F_RSSI		0x00020000
236 #define HOSTAPD_FRAME_F_RATE		0x00040000
237 #define HOSTAPD_FRAME_F_CHANNEL		0x00080000
238 #define HOSTAPD_FRAME_F_RADIOTAP_M	0x000e0000
239 #define HOSTAPD_FRAME_F_M		0x0fffffff
240 #define HOSTAPD_FRAME_F_RET_OK		0x00000000
241 #define HOSTAPD_FRAME_F_RET_QUICK	0x10000000
242 #define HOSTAPD_FRAME_F_RET_SKIP	0x20000000
243 #define HOSTAPD_FRAME_F_RET_M		0xf0000000
244 #define HOSTAPD_FRAME_F_RET_S		28
245 
246 #define HOSTAPD_FRAME_TABLE						\
247 	(HOSTAPD_FRAME_F_FROM_TABLE | HOSTAPD_FRAME_F_TO_TABLE |	\
248 	HOSTAPD_FRAME_F_BSSID_TABLE)
249 #define HOSTAPD_FRAME_N							\
250 	(HOSTAPD_FRAME_F_FROM_N | HOSTAPD_FRAME_F_TO_N |		\
251 	HOSTAPD_FRAME_F_BSSID_N)
252 
253 	struct hostapd_apme		*f_apme;
254 	struct hostapd_table		*f_from, *f_to, *f_bssid;
255 	struct timeval			f_limit, f_then, f_last;
256 	long				f_rate, f_rate_intval;
257 	long				f_rate_cnt, f_rate_delay;
258 
259 	enum hostapd_op			f_rssi_op, f_txrate_op, f_chan_op;
260 	short				f_rssi, f_txrate, f_chan;
261 
262 	enum hostapd_action		f_action;
263 	u_int32_t			f_action_flags;
264 
265 #define HOSTAPD_ACTION_VERBOSE		0x00000001
266 
267 	struct hostapd_action_data	f_action_data;
268 
269 	TAILQ_ENTRY(hostapd_frame)	f_entries;
270 };
271 
272 struct hostapd_apme {
273 	int				a_raw;
274 	u_int				a_rawlen;
275 	struct event			a_ev;
276 	char				a_iface[IFNAMSIZ];
277 	u_int8_t			a_bssid[IEEE80211_ADDR_LEN];
278 	void				*a_cfg;
279 	struct sockaddr_in		a_addr;
280 
281 	struct event			a_chanev;
282 	u_int8_t			*a_chanavail;
283 	u_int8_t			a_curchan;
284 	u_int				a_maxchan;
285 	struct ieee80211chanreq		a_chanreq;
286 
287 	TAILQ_ENTRY(hostapd_apme)	a_entries;
288 };
289 
290 #ifndef IEEE80211_CHAN_MAX
291 #define IEEE80211_CHAN_MAX	255
292 #endif
293 
294 #define HOSTAPD_HOPPER_MDELAY	800
295 
296 struct hostapd_iapp {
297 	u_int16_t			i_cnt;
298 	int				i_raw;
299 	char				i_iface[IFNAMSIZ];
300 	int				i_udp;
301 	struct event			i_udp_ev;
302 	u_int16_t			i_udp_port;
303 	struct sockaddr_in		i_addr;
304 	struct sockaddr_in		i_broadcast;
305 	struct sockaddr_in		i_multicast;
306 	u_int8_t			i_ttl;
307 	u_int8_t			i_flags;
308 
309 #define HOSTAPD_IAPP_F_ADD_NOTIFY	0x01
310 #define HOSTAPD_IAPP_F_RADIOTAP		0x02
311 #define HOSTAPD_IAPP_F_ROAMING_ADDRESS	0x04
312 #define HOSTAPD_IAPP_F_ROAMING_ROUTE	0x08
313 #define HOSTAPD_IAPP_F_DEFAULT							\
314 	(HOSTAPD_IAPP_F_ADD_NOTIFY | HOSTAPD_IAPP_F_RADIOTAP)
315 #define HOSTAPD_IAPP_F_ROAMING							\
316 	(HOSTAPD_IAPP_F_ROAMING_ROUTE | HOSTAPD_IAPP_F_ROAMING_ADDRESS)
317 #define HOSTAPD_IAPP_F_ADD		\
318 	(HOSTAPD_IAPP_F_ADD_NOTIFY | HOSTAPD_IAPP_F_ROAMING)
319 
320 	struct hostapd_table		*i_addr_tbl;
321 	struct hostapd_table		*i_route_tbl;
322 };
323 
324 struct hostapd_config {
325 	int				c_apme_ctl;
326 	u_int				c_apme_dlt;
327 	struct timeval			c_apme_hopdelay;
328 
329 	struct hostapd_iapp		c_iapp;
330 
331 	int				c_rtsock;
332 	int				c_rtseq;
333 
334 	u_int8_t			c_flags;
335 
336 #define HOSTAPD_CFG_F_APME		0x01
337 #define HOSTAPD_CFG_F_IAPP		0x02
338 #define HOSTAPD_CFG_F_IAPP_PASSIVE	0x04
339 #define HOSTAPD_CFG_F_RAW		0x08
340 #define HOSTAPD_CFG_F_UDP		0x10
341 #define HOSTAPD_CFG_F_BRDCAST		0x20
342 #define HOSTAPD_CFG_F_PRIV		0x40
343 
344 	struct event			c_priv_ev;
345 
346 	char				c_config[PATH_MAX];
347 
348 	u_int				c_verbose;
349 	u_int				c_debug;
350 	u_int				c_id;
351 
352 	struct hostapd_counter		c_stats;
353 
354 	TAILQ_HEAD(, hostapd_apme)	c_apmes;
355 	TAILQ_HEAD(, hostapd_table)	c_tables;
356 	TAILQ_HEAD(, hostapd_frame)	c_frames;
357 };
358 
359 #define	HOSTAPD_USER	"_hostapd"
360 #define HOSTAPD_CONFIG	"/etc/hostapd.conf"
361 #define HOSTAPD_DLT	DLT_IEEE802_11
362 
363 #define HOSTAPD_LOG		0
364 #define HOSTAPD_LOG_VERBOSE	1
365 #define HOSTAPD_LOG_DEBUG	2
366 
367 #define PRINTF			hostapd_printf
368 #define etheraddr_string(_s)	ether_ntoa((struct ether_addr*)_s)
369 #define TTEST2(var, l)		(						\
370 	snapend - (l) <= snapend && (const u_char *)&(var) <= snapend - (l)	\
371 )
372 #define TTEST(var)		TTEST2(var, sizeof(var))
373 #define TCHECK2(var, l)		if (!TTEST2(var, l)) goto trunc
374 #define TCHECK(var)		TCHECK2(var, sizeof(var))
375 
376 __BEGIN_DECLS
377 
378 void	 hostapd_log(u_int, const char *, ...);
379 void	 hostapd_printf(const char *, ...);
380 void	 hostapd_fatal(const char *, ...);
381 int	 hostapd_bpf_open(u_int);
382 void	 hostapd_cleanup(struct hostapd_config *);
383 int	 hostapd_check_file_secrecy(int, const char *);
384 void	 hostapd_randval(u_int8_t *, const u_int)
385 	    __attribute__((__bounded__(__buffer__, 1, 2)));
386 
387 struct hostapd_table *hostapd_table_add(struct hostapd_config *,
388 	    const char *);
389 struct hostapd_table *hostapd_table_lookup(struct hostapd_config *,
390 	    const char *);
391 struct hostapd_entry *hostapd_entry_add(struct hostapd_table *,
392 	    u_int8_t *);
393 struct hostapd_entry *hostapd_entry_lookup(struct hostapd_table *,
394 	    u_int8_t *);
395 void	 hostapd_entry_update(struct hostapd_table *,
396 	    struct hostapd_entry *);
397 
398 RB_PROTOTYPE(hostapd_tree, hostapd_entry, e_nodes, hostapd_entry_cmp);
399 
400 int	 hostapd_parse_file(struct hostapd_config *);
401 int	 hostapd_parse_symset(char *);
402 
403 void	 hostapd_priv_init(struct hostapd_config *);
404 int	 hostapd_priv_llc_xid(struct hostapd_config *, struct hostapd_node *);
405 void	 hostapd_priv_apme_bssid(struct hostapd_apme *);
406 int	 hostapd_priv_apme_getnode(struct hostapd_apme *,
407 	    struct hostapd_node *);
408 int	 hostapd_priv_apme_setnode(struct hostapd_apme *,
409 	    struct hostapd_node *node, int);
410 int	 hostapd_priv_roaming(struct hostapd_apme *, struct hostapd_node *,
411 	    int);
412 
413 void	 hostapd_apme_init(struct hostapd_apme *);
414 int	 hostapd_apme_deauth(struct hostapd_apme *);
415 int	 hostapd_apme_add(struct hostapd_config *, const char *);
416 void	 hostapd_apme_term(struct hostapd_apme *);
417 struct hostapd_apme *hostapd_apme_lookup(struct hostapd_config *,
418 	    const char *);
419 void	 hostapd_apme_input(int, short, void *);
420 int	 hostapd_apme_output(struct hostapd_apme *,
421 	    struct hostapd_ieee80211_frame *);
422 int	 hostapd_apme_addnode(struct hostapd_apme *,
423 	    struct hostapd_node *node);
424 int	 hostapd_apme_delnode(struct hostapd_apme *,
425 	    struct hostapd_node *node);
426 int	 hostapd_apme_offset(struct hostapd_apme *, u_int8_t *,
427 	    const u_int);
428 struct hostapd_apme *hostapd_apme_addhopper(struct hostapd_config *,
429 	    const char *);
430 void	 hostapd_apme_sethopper(struct hostapd_apme *, int);
431 
432 void	 hostapd_iapp_init(struct hostapd_config *);
433 void	 hostapd_iapp_term(struct hostapd_config *);
434 int	 hostapd_iapp_add_notify(struct hostapd_apme *,
435 	    struct hostapd_node *);
436 int	 hostapd_iapp_radiotap(struct hostapd_apme *,
437 	    u_int8_t *, const u_int);
438 void	 hostapd_iapp_input(int, short, void *);
439 
440 void	 hostapd_llc_init(struct hostapd_config *);
441 int	 hostapd_llc_send_xid(struct hostapd_config *, struct hostapd_node *);
442 
443 int	 hostapd_handle_input(struct hostapd_apme *, u_int8_t *, u_int);
444 
445 void	 hostapd_print_ieee80211(u_int, u_int, u_int8_t *, u_int);
446 
447 void	 hostapd_roaming_init(struct hostapd_config *);
448 void	 hostapd_roaming_term(struct hostapd_apme *);
449 int	 hostapd_roaming(struct hostapd_apme *, struct hostapd_node *, int);
450 int	 hostapd_roaming_add(struct hostapd_apme *,
451 	    struct hostapd_node *node);
452 int	 hostapd_roaming_del(struct hostapd_apme *,
453 	    struct hostapd_node *node);
454 
455 __END_DECLS
456 
457 #endif /* _HOSTAPD_H */
458