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