458 lines
13 KiB
C
458 lines
13 KiB
C
/* $OpenBSD: hostapd.h,v 1.21 2015/01/16 06:40:17 deraadt Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@openbsd.org>
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#ifndef _HOSTAPD_H
|
|
#define _HOSTAPD_H
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/tree.h>
|
|
|
|
#include <net/if.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
|
|
#include <errno.h>
|
|
#include <event.h>
|
|
#include <syslog.h>
|
|
|
|
#include <net80211/ieee80211.h>
|
|
#include <net80211/ieee80211_ioctl.h>
|
|
|
|
/*
|
|
* hostapd (IAPP) <-> Host AP (APME)
|
|
*/
|
|
|
|
struct hostapd_node {
|
|
u_int8_t ni_macaddr[IEEE80211_ADDR_LEN];
|
|
u_int8_t ni_bssid[IEEE80211_ADDR_LEN];
|
|
u_int32_t ni_associd;
|
|
u_int16_t ni_capinfo;
|
|
u_int16_t ni_flags;
|
|
u_int16_t ni_rxseq;
|
|
u_int16_t ni_rssi;
|
|
};
|
|
|
|
/*
|
|
* IAPP -> switches (LLC)
|
|
*/
|
|
|
|
struct hostapd_llc {
|
|
struct ether_header x_hdr;
|
|
struct llc x_llc;
|
|
} __packed;
|
|
|
|
#define IAPP_LLC LLC_XID
|
|
#define IAPP_LLC_XID 0x81
|
|
#define IAPP_LLC_CLASS 1
|
|
#define IAPP_LLC_WINDOW 1 << 1
|
|
|
|
/*
|
|
* hostapd configuration
|
|
*/
|
|
|
|
struct hostapd_counter {
|
|
u_int64_t cn_tx_llc; /* sent LLC messages */
|
|
u_int64_t cn_rx_iapp; /* received IAPP messages */
|
|
u_int64_t cn_tx_iapp; /* sent IAPP messages */
|
|
u_int64_t cn_rx_apme; /* received Host AP messages */
|
|
u_int64_t cn_tx_apme; /* sent Host AP messages */
|
|
u_int64_t cn_rtap_miss; /* missing radiotap field */
|
|
};
|
|
|
|
#define HOSTAPD_ENTRY_MASK_ADD(_a, _m) do { \
|
|
(_a)[0] &= (_m)[0]; \
|
|
(_a)[1] &= (_m)[1]; \
|
|
(_a)[2] &= (_m)[2]; \
|
|
(_a)[3] &= (_m)[3]; \
|
|
(_a)[4] &= (_m)[4]; \
|
|
(_a)[5] &= (_m)[5]; \
|
|
} while (0);
|
|
#define HOSTAPD_ENTRY_MASK_MATCH(_e, _b) ( \
|
|
((_e)->e_lladdr[0] == ((_b)[0] & (_e)->e_addr.a_mask[0])) && \
|
|
((_e)->e_lladdr[1] == ((_b)[1] & (_e)->e_addr.a_mask[1])) && \
|
|
((_e)->e_lladdr[2] == ((_b)[2] & (_e)->e_addr.a_mask[2])) && \
|
|
((_e)->e_lladdr[3] == ((_b)[3] & (_e)->e_addr.a_mask[3])) && \
|
|
((_e)->e_lladdr[4] == ((_b)[4] & (_e)->e_addr.a_mask[4])) && \
|
|
((_e)->e_lladdr[5] == ((_b)[5] & (_e)->e_addr.a_mask[5])) \
|
|
)
|
|
|
|
struct hostapd_inaddr {
|
|
sa_family_t in_af;
|
|
union {
|
|
struct in_addr v4;
|
|
struct in6_addr v6;
|
|
} in_v;
|
|
int in_netmask;
|
|
};
|
|
|
|
#define in_v4 in_v.v4
|
|
#define in_v6 in_v.v6
|
|
|
|
struct hostapd_entry {
|
|
u_int8_t e_lladdr[IEEE80211_ADDR_LEN];
|
|
u_int8_t e_flags;
|
|
|
|
#define HOSTAPD_ENTRY_F_LLADDR 0x00
|
|
#define HOSTAPD_ENTRY_F_MASK 0x01
|
|
#define HOSTAPD_ENTRY_F_INADDR 0x02
|
|
|
|
union {
|
|
u_int8_t a_mask[IEEE80211_ADDR_LEN];
|
|
struct hostapd_inaddr a_inaddr;
|
|
} e_addr;
|
|
|
|
RB_ENTRY(hostapd_entry) e_nodes;
|
|
TAILQ_ENTRY(hostapd_entry) e_entries;
|
|
};
|
|
|
|
#define e_mask e_addr.a_mask
|
|
#define e_inaddr e_addr.a_inaddr
|
|
|
|
#define HOSTAPD_TABLE_NAMELEN 32
|
|
|
|
RB_HEAD(hostapd_tree, hostapd_entry);
|
|
|
|
struct hostapd_table {
|
|
char t_name[HOSTAPD_TABLE_NAMELEN];
|
|
u_int8_t t_flags;
|
|
|
|
#define HOSTAPD_TABLE_F_CONST 0x01
|
|
|
|
struct hostapd_tree t_tree;
|
|
TAILQ_HEAD(, hostapd_entry) t_mask_head;
|
|
TAILQ_ENTRY(hostapd_table) t_entries;
|
|
};
|
|
|
|
struct hostapd_radiotap {
|
|
u_int32_t r_present;
|
|
u_int8_t r_txrate;
|
|
u_int16_t r_chan;
|
|
u_int16_t r_chan_flags;
|
|
u_int8_t r_rssi;
|
|
u_int8_t r_max_rssi;
|
|
};
|
|
#define HOSTAPD_RADIOTAP_F(_x) (1 << IEEE80211_RADIOTAP_##_x)
|
|
|
|
struct hostapd_ieee80211_frame {
|
|
u_int8_t i_fc[2];
|
|
u_int8_t i_dur[2];
|
|
u_int8_t i_from[IEEE80211_ADDR_LEN];
|
|
u_int8_t i_to[IEEE80211_ADDR_LEN];
|
|
u_int8_t i_bssid[IEEE80211_ADDR_LEN];
|
|
u_int8_t i_seq[2];
|
|
void *i_data;
|
|
u_int i_data_len;
|
|
};
|
|
|
|
enum hostapd_action {
|
|
HOSTAPD_ACTION_NONE = 0,
|
|
HOSTAPD_ACTION_LOG = 1,
|
|
HOSTAPD_ACTION_RADIOTAP = 2,
|
|
HOSTAPD_ACTION_FRAME = 3,
|
|
HOSTAPD_ACTION_ADDNODE = 4,
|
|
HOSTAPD_ACTION_DELNODE = 5,
|
|
HOSTAPD_ACTION_RESEND = 6
|
|
};
|
|
|
|
enum hostapd_op {
|
|
HOSTAPD_OP_EQ = 0,
|
|
HOSTAPD_OP_NE = 1,
|
|
HOSTAPD_OP_LE = 2,
|
|
HOSTAPD_OP_LT = 3,
|
|
HOSTAPD_OP_GE = 4,
|
|
HOSTAPD_OP_GT = 5
|
|
};
|
|
|
|
struct hostapd_action_data {
|
|
union {
|
|
struct hostapd_ieee80211_frame u_frame;
|
|
u_int8_t u_lladdr[IEEE80211_ADDR_LEN];
|
|
} a_data;
|
|
u_int16_t a_flags;
|
|
|
|
#define HOSTAPD_ACTION_F_REF_FROM 0x0001
|
|
#define HOSTAPD_ACTION_F_REF_TO 0x0002
|
|
#define HOSTAPD_ACTION_F_REF_BSSID 0x0004
|
|
#define HOSTAPD_ACTION_F_REF_RANDOM 0x0008
|
|
#define HOSTAPD_ACTION_F_REF_FROM_M 0x000f
|
|
#define HOSTAPD_ACTION_F_REF_FROM_S 0
|
|
#define HOSTAPD_ACTION_F_REF_TO_M 0x00f0
|
|
#define HOSTAPD_ACTION_F_REF_TO_S 4
|
|
#define HOSTAPD_ACTION_F_REF_BSSID_M 0x0f00
|
|
#define HOSTAPD_ACTION_F_REF_BSSID_S 8
|
|
#define HOSTAPD_ACTION_F_REF_M 0x0fff
|
|
#define HOSTAPD_ACTION_F_OPT_DIR_AUTO 0x1000
|
|
#define HOSTAPD_ACTION_F_OPT_LLADDR 0x2000
|
|
#define HOSTAPD_ACTION_F_OPT_TABLE 0x4000
|
|
};
|
|
|
|
#define a_frame a_data.u_frame
|
|
#define a_lladdr a_data.u_lladdr
|
|
|
|
struct hostapd_frame {
|
|
struct hostapd_ieee80211_frame f_frame;
|
|
u_int32_t f_radiotap;
|
|
|
|
u_int32_t f_flags;
|
|
|
|
#define HOSTAPD_FRAME_F_TYPE 0x00000001
|
|
#define HOSTAPD_FRAME_F_TYPE_N 0x00000002
|
|
#define HOSTAPD_FRAME_F_SUBTYPE 0x00000004
|
|
#define HOSTAPD_FRAME_F_SUBTYPE_N 0x00000008
|
|
#define HOSTAPD_FRAME_F_DIR 0x00000010
|
|
#define HOSTAPD_FRAME_F_DIR_N 0x00000020
|
|
#define HOSTAPD_FRAME_F_FROM 0x00000040
|
|
#define HOSTAPD_FRAME_F_FROM_N 0x00000080
|
|
#define HOSTAPD_FRAME_F_FROM_TABLE 0x00000100
|
|
#define HOSTAPD_FRAME_F_FROM_M 0x000001c0
|
|
#define HOSTAPD_FRAME_F_TO 0x00000200
|
|
#define HOSTAPD_FRAME_F_TO_N 0x00000400
|
|
#define HOSTAPD_FRAME_F_TO_TABLE 0x00000800
|
|
#define HOSTAPD_FRAME_F_TO_M 0x00000e00
|
|
#define HOSTAPD_FRAME_F_BSSID 0x00001000
|
|
#define HOSTAPD_FRAME_F_BSSID_N 0x00002000
|
|
#define HOSTAPD_FRAME_F_BSSID_TABLE 0x00004000
|
|
#define HOSTAPD_FRAME_F_BSSID_M 0x00007000
|
|
#define HOSTAPD_FRAME_F_APME 0x00008000
|
|
#define HOSTAPD_FRAME_F_APME_N 0x00010000
|
|
#define HOSTAPD_FRAME_F_APME_M 0x00018000
|
|
#define HOSTAPD_FRAME_F_RSSI 0x00020000
|
|
#define HOSTAPD_FRAME_F_RATE 0x00040000
|
|
#define HOSTAPD_FRAME_F_CHANNEL 0x00080000
|
|
#define HOSTAPD_FRAME_F_RADIOTAP_M 0x000e0000
|
|
#define HOSTAPD_FRAME_F_M 0x0fffffff
|
|
#define HOSTAPD_FRAME_F_RET_OK 0x00000000
|
|
#define HOSTAPD_FRAME_F_RET_QUICK 0x10000000
|
|
#define HOSTAPD_FRAME_F_RET_SKIP 0x20000000
|
|
#define HOSTAPD_FRAME_F_RET_M 0xf0000000
|
|
#define HOSTAPD_FRAME_F_RET_S 28
|
|
|
|
#define HOSTAPD_FRAME_TABLE \
|
|
(HOSTAPD_FRAME_F_FROM_TABLE | HOSTAPD_FRAME_F_TO_TABLE | \
|
|
HOSTAPD_FRAME_F_BSSID_TABLE)
|
|
#define HOSTAPD_FRAME_N \
|
|
(HOSTAPD_FRAME_F_FROM_N | HOSTAPD_FRAME_F_TO_N | \
|
|
HOSTAPD_FRAME_F_BSSID_N)
|
|
|
|
struct hostapd_apme *f_apme;
|
|
struct hostapd_table *f_from, *f_to, *f_bssid;
|
|
struct timeval f_limit, f_then, f_last;
|
|
long f_rate, f_rate_intval;
|
|
long f_rate_cnt, f_rate_delay;
|
|
|
|
enum hostapd_op f_rssi_op, f_txrate_op, f_chan_op;
|
|
short f_rssi, f_txrate, f_chan;
|
|
|
|
enum hostapd_action f_action;
|
|
u_int32_t f_action_flags;
|
|
|
|
#define HOSTAPD_ACTION_VERBOSE 0x00000001
|
|
|
|
struct hostapd_action_data f_action_data;
|
|
|
|
TAILQ_ENTRY(hostapd_frame) f_entries;
|
|
};
|
|
|
|
struct hostapd_apme {
|
|
int a_raw;
|
|
u_int a_rawlen;
|
|
struct event a_ev;
|
|
char a_iface[IFNAMSIZ];
|
|
u_int8_t a_bssid[IEEE80211_ADDR_LEN];
|
|
void *a_cfg;
|
|
struct sockaddr_in a_addr;
|
|
|
|
struct event a_chanev;
|
|
u_int8_t *a_chanavail;
|
|
u_int8_t a_curchan;
|
|
u_int a_maxchan;
|
|
struct ieee80211chanreq a_chanreq;
|
|
|
|
TAILQ_ENTRY(hostapd_apme) a_entries;
|
|
};
|
|
|
|
#ifndef IEEE80211_CHAN_MAX
|
|
#define IEEE80211_CHAN_MAX 255
|
|
#endif
|
|
|
|
#define HOSTAPD_HOPPER_MDELAY 800
|
|
|
|
struct hostapd_iapp {
|
|
u_int16_t i_cnt;
|
|
int i_raw;
|
|
char i_iface[IFNAMSIZ];
|
|
int i_udp;
|
|
struct event i_udp_ev;
|
|
u_int16_t i_udp_port;
|
|
struct sockaddr_in i_addr;
|
|
struct sockaddr_in i_broadcast;
|
|
struct sockaddr_in i_multicast;
|
|
u_int8_t i_ttl;
|
|
u_int8_t i_flags;
|
|
|
|
#define HOSTAPD_IAPP_F_ADD_NOTIFY 0x01
|
|
#define HOSTAPD_IAPP_F_RADIOTAP 0x02
|
|
#define HOSTAPD_IAPP_F_ROAMING_ADDRESS 0x04
|
|
#define HOSTAPD_IAPP_F_ROAMING_ROUTE 0x08
|
|
#define HOSTAPD_IAPP_F_DEFAULT \
|
|
(HOSTAPD_IAPP_F_ADD_NOTIFY | HOSTAPD_IAPP_F_RADIOTAP)
|
|
#define HOSTAPD_IAPP_F_ROAMING \
|
|
(HOSTAPD_IAPP_F_ROAMING_ROUTE | HOSTAPD_IAPP_F_ROAMING_ADDRESS)
|
|
#define HOSTAPD_IAPP_F_ADD \
|
|
(HOSTAPD_IAPP_F_ADD_NOTIFY | HOSTAPD_IAPP_F_ROAMING)
|
|
|
|
struct hostapd_table *i_addr_tbl;
|
|
struct hostapd_table *i_route_tbl;
|
|
};
|
|
|
|
struct hostapd_config {
|
|
int c_apme_ctl;
|
|
u_int c_apme_dlt;
|
|
struct timeval c_apme_hopdelay;
|
|
|
|
struct hostapd_iapp c_iapp;
|
|
|
|
int c_rtsock;
|
|
int c_rtseq;
|
|
|
|
u_int8_t c_flags;
|
|
|
|
#define HOSTAPD_CFG_F_APME 0x01
|
|
#define HOSTAPD_CFG_F_IAPP 0x02
|
|
#define HOSTAPD_CFG_F_IAPP_PASSIVE 0x04
|
|
#define HOSTAPD_CFG_F_RAW 0x08
|
|
#define HOSTAPD_CFG_F_UDP 0x10
|
|
#define HOSTAPD_CFG_F_BRDCAST 0x20
|
|
#define HOSTAPD_CFG_F_PRIV 0x40
|
|
|
|
struct event c_priv_ev;
|
|
|
|
char c_config[PATH_MAX];
|
|
|
|
u_int c_verbose;
|
|
u_int c_debug;
|
|
u_int c_id;
|
|
|
|
struct hostapd_counter c_stats;
|
|
|
|
TAILQ_HEAD(, hostapd_apme) c_apmes;
|
|
TAILQ_HEAD(, hostapd_table) c_tables;
|
|
TAILQ_HEAD(, hostapd_frame) c_frames;
|
|
};
|
|
|
|
#define HOSTAPD_USER "_hostapd"
|
|
#define HOSTAPD_CONFIG "/etc/hostapd.conf"
|
|
#define HOSTAPD_DLT DLT_IEEE802_11
|
|
|
|
#define HOSTAPD_LOG 0
|
|
#define HOSTAPD_LOG_VERBOSE 1
|
|
#define HOSTAPD_LOG_DEBUG 2
|
|
|
|
#define PRINTF hostapd_printf
|
|
#define etheraddr_string(_s) ether_ntoa((struct ether_addr*)_s)
|
|
#define TTEST2(var, l) ( \
|
|
snapend - (l) <= snapend && (const u_char *)&(var) <= snapend - (l) \
|
|
)
|
|
#define TTEST(var) TTEST2(var, sizeof(var))
|
|
#define TCHECK2(var, l) if (!TTEST2(var, l)) goto trunc
|
|
#define TCHECK(var) TCHECK2(var, sizeof(var))
|
|
|
|
__BEGIN_DECLS
|
|
|
|
void hostapd_log(u_int, const char *, ...);
|
|
void hostapd_printf(const char *, ...);
|
|
void hostapd_fatal(const char *, ...);
|
|
int hostapd_bpf_open(u_int);
|
|
void hostapd_cleanup(struct hostapd_config *);
|
|
int hostapd_check_file_secrecy(int, const char *);
|
|
void hostapd_randval(u_int8_t *, const u_int)
|
|
__attribute__((__bounded__(__buffer__, 1, 2)));
|
|
|
|
struct hostapd_table *hostapd_table_add(struct hostapd_config *,
|
|
const char *);
|
|
struct hostapd_table *hostapd_table_lookup(struct hostapd_config *,
|
|
const char *);
|
|
struct hostapd_entry *hostapd_entry_add(struct hostapd_table *,
|
|
u_int8_t *);
|
|
struct hostapd_entry *hostapd_entry_lookup(struct hostapd_table *,
|
|
u_int8_t *);
|
|
void hostapd_entry_update(struct hostapd_table *,
|
|
struct hostapd_entry *);
|
|
|
|
RB_PROTOTYPE(hostapd_tree, hostapd_entry, e_nodes, hostapd_entry_cmp);
|
|
|
|
int hostapd_parse_file(struct hostapd_config *);
|
|
int hostapd_parse_symset(char *);
|
|
|
|
void hostapd_priv_init(struct hostapd_config *);
|
|
int hostapd_priv_llc_xid(struct hostapd_config *, struct hostapd_node *);
|
|
void hostapd_priv_apme_bssid(struct hostapd_apme *);
|
|
int hostapd_priv_apme_getnode(struct hostapd_apme *,
|
|
struct hostapd_node *);
|
|
int hostapd_priv_apme_setnode(struct hostapd_apme *,
|
|
struct hostapd_node *node, int);
|
|
int hostapd_priv_roaming(struct hostapd_apme *, struct hostapd_node *,
|
|
int);
|
|
|
|
void hostapd_apme_init(struct hostapd_apme *);
|
|
int hostapd_apme_deauth(struct hostapd_apme *);
|
|
int hostapd_apme_add(struct hostapd_config *, const char *);
|
|
void hostapd_apme_term(struct hostapd_apme *);
|
|
struct hostapd_apme *hostapd_apme_lookup(struct hostapd_config *,
|
|
const char *);
|
|
void hostapd_apme_input(int, short, void *);
|
|
int hostapd_apme_output(struct hostapd_apme *,
|
|
struct hostapd_ieee80211_frame *);
|
|
int hostapd_apme_addnode(struct hostapd_apme *,
|
|
struct hostapd_node *node);
|
|
int hostapd_apme_delnode(struct hostapd_apme *,
|
|
struct hostapd_node *node);
|
|
int hostapd_apme_offset(struct hostapd_apme *, u_int8_t *,
|
|
const u_int);
|
|
struct hostapd_apme *hostapd_apme_addhopper(struct hostapd_config *,
|
|
const char *);
|
|
void hostapd_apme_sethopper(struct hostapd_apme *, int);
|
|
|
|
void hostapd_iapp_init(struct hostapd_config *);
|
|
void hostapd_iapp_term(struct hostapd_config *);
|
|
int hostapd_iapp_add_notify(struct hostapd_apme *,
|
|
struct hostapd_node *);
|
|
int hostapd_iapp_radiotap(struct hostapd_apme *,
|
|
u_int8_t *, const u_int);
|
|
void hostapd_iapp_input(int, short, void *);
|
|
|
|
void hostapd_llc_init(struct hostapd_config *);
|
|
int hostapd_llc_send_xid(struct hostapd_config *, struct hostapd_node *);
|
|
|
|
int hostapd_handle_input(struct hostapd_apme *, u_int8_t *, u_int);
|
|
|
|
void hostapd_print_ieee80211(u_int, u_int, u_int8_t *, u_int);
|
|
|
|
void hostapd_roaming_init(struct hostapd_config *);
|
|
void hostapd_roaming_term(struct hostapd_apme *);
|
|
int hostapd_roaming(struct hostapd_apme *, struct hostapd_node *, int);
|
|
int hostapd_roaming_add(struct hostapd_apme *,
|
|
struct hostapd_node *node);
|
|
int hostapd_roaming_del(struct hostapd_apme *,
|
|
struct hostapd_node *node);
|
|
|
|
__END_DECLS
|
|
|
|
#endif /* _HOSTAPD_H */
|