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