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