Remove IAPP functionality from hostapd
IEEE Std 802.11F-2003 was withdrawn in 2006 and as such it has not been maintained nor is there any expectation of the withdrawn trial-use recommended practice to be maintained in the future. Furthermore, implementation of IAPP in hostapd was not complete, i.e., only parts of the recommended practice were included. The main item of some real use long time ago was the Layer 2 Update frame to update bridges when a STA roams within an ESS, but that functionality has, in practice, been moved to kernel drivers to provide better integration with the networking stack. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
d2d444deef
commit
018edec9b2
16 changed files with 1 additions and 633 deletions
|
@ -205,11 +205,6 @@ endif
|
|||
|
||||
L_CFLAGS += -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_UNIX
|
||||
|
||||
ifdef CONFIG_IAPP
|
||||
L_CFLAGS += -DCONFIG_IAPP
|
||||
OBJS += src/ap/iapp.c
|
||||
endif
|
||||
|
||||
ifdef CONFIG_RSN_PREAUTH
|
||||
L_CFLAGS += -DCONFIG_RSN_PREAUTH
|
||||
CONFIG_L2_PACKET=y
|
||||
|
|
|
@ -248,11 +248,6 @@ ifndef CONFIG_NO_CTRL_IFACE
|
|||
CFLAGS += -DCONFIG_CTRL_IFACE
|
||||
endif
|
||||
|
||||
ifdef CONFIG_IAPP
|
||||
CFLAGS += -DCONFIG_IAPP
|
||||
OBJS += ../src/ap/iapp.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_RSN_PREAUTH
|
||||
CFLAGS += -DCONFIG_RSN_PREAUTH
|
||||
CONFIG_L2_PACKET=y
|
||||
|
|
|
@ -38,9 +38,6 @@ CONFIG_DRIVER_NL80211_QCA=y
|
|||
# Driver interface for no driver (e.g., RADIUS server only)
|
||||
#CONFIG_DRIVER_NONE=y
|
||||
|
||||
# IEEE 802.11F/IAPP
|
||||
#CONFIG_IAPP=y
|
||||
|
||||
# WPA2/IEEE 802.11i RSN pre-authentication
|
||||
#CONFIG_RSN_PREAUTH=y
|
||||
|
||||
|
|
|
@ -2712,8 +2712,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
|||
bss->eapol_key_index_workaround = atoi(pos);
|
||||
#ifdef CONFIG_IAPP
|
||||
} else if (os_strcmp(buf, "iapp_interface") == 0) {
|
||||
bss->ieee802_11f = 1;
|
||||
os_strlcpy(bss->iapp_iface, pos, sizeof(bss->iapp_iface));
|
||||
wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used");
|
||||
#endif /* CONFIG_IAPP */
|
||||
} else if (os_strcmp(buf, "own_ip_addr") == 0) {
|
||||
if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) {
|
||||
|
|
|
@ -44,9 +44,6 @@ CONFIG_LIBNL32=y
|
|||
# Driver interface for no driver (e.g., RADIUS server only)
|
||||
#CONFIG_DRIVER_NONE=y
|
||||
|
||||
# IEEE 802.11F/IAPP
|
||||
CONFIG_IAPP=y
|
||||
|
||||
# WPA2/IEEE 802.11i RSN pre-authentication
|
||||
CONFIG_RSN_PREAUTH=y
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ interface=wlan0
|
|||
# bit 2 (4) = RADIUS
|
||||
# bit 3 (8) = WPA
|
||||
# bit 4 (16) = driver interface
|
||||
# bit 5 (32) = IAPP
|
||||
# bit 6 (64) = MLME
|
||||
#
|
||||
# Levels (minimum value for logged events):
|
||||
|
@ -1243,11 +1242,6 @@ eap_server=0
|
|||
# Whether to enable ERP on the EAP server.
|
||||
#eap_server_erp=1
|
||||
|
||||
##### IEEE 802.11f - Inter-Access Point Protocol (IAPP) #######################
|
||||
|
||||
# Interface to be used for IAPP broadcast packets
|
||||
#iapp_interface=eth0
|
||||
|
||||
|
||||
##### RADIUS client configuration #############################################
|
||||
# for IEEE 802.1X with external Authentication Server, IEEE 802.11
|
||||
|
|
|
@ -81,9 +81,6 @@ static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
|
|||
case HOSTAPD_MODULE_DRIVER:
|
||||
module_str = "DRIVER";
|
||||
break;
|
||||
case HOSTAPD_MODULE_IAPP:
|
||||
module_str = "IAPP";
|
||||
break;
|
||||
case HOSTAPD_MODULE_MLME:
|
||||
module_str = "MLME";
|
||||
break;
|
||||
|
|
|
@ -18,7 +18,6 @@ CFLAGS += -DCONFIG_IEEE80211R_AP
|
|||
CFLAGS += -DCONFIG_WPS
|
||||
CFLAGS += -DCONFIG_PROXYARP
|
||||
CFLAGS += -DCONFIG_IPV6
|
||||
CFLAGS += -DCONFIG_IAPP
|
||||
CFLAGS += -DCONFIG_AIRTIME_POLICY
|
||||
|
||||
LIB_OBJS= \
|
||||
|
@ -41,7 +40,6 @@ LIB_OBJS= \
|
|||
hostapd.o \
|
||||
hs20.o \
|
||||
hw_features.o \
|
||||
iapp.o \
|
||||
ieee802_11_auth.o \
|
||||
ieee802_11.o \
|
||||
ieee802_11_ht.o \
|
||||
|
|
|
@ -325,10 +325,6 @@ struct hostapd_bss_config {
|
|||
int erp_send_reauth_start;
|
||||
char *erp_domain;
|
||||
|
||||
int ieee802_11f; /* use IEEE 802.11f (IAPP) */
|
||||
char iapp_iface[IFNAMSIZ + 1]; /* interface used with IAPP broadcast
|
||||
* frames */
|
||||
|
||||
enum macaddr_acl {
|
||||
ACCEPT_UNLESS_DENIED = 0,
|
||||
DENY_UNLESS_ACCEPTED = 1,
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "accounting.h"
|
||||
#include "ap_list.h"
|
||||
#include "beacon.h"
|
||||
#include "iapp.h"
|
||||
#include "ieee802_1x.h"
|
||||
#include "ieee802_11_auth.h"
|
||||
#include "vlan_init.h"
|
||||
|
@ -361,8 +360,6 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd)
|
|||
hapd->beacon_set_done = 0;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
|
||||
iapp_deinit(hapd->iapp);
|
||||
hapd->iapp = NULL;
|
||||
accounting_deinit(hapd);
|
||||
hostapd_deinit_wpa(hapd);
|
||||
vlan_deinit(hapd);
|
||||
|
@ -1296,13 +1293,6 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (conf->ieee802_11f &&
|
||||
(hapd->iapp = iapp_init(hapd, conf->iapp_iface)) == NULL) {
|
||||
wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization "
|
||||
"failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
if (gas_serv_init(hapd)) {
|
||||
wpa_printf(MSG_ERROR, "GAS server initialization failed");
|
||||
|
@ -3056,10 +3046,6 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
|
|||
hostapd_prune_associations(hapd, sta->addr);
|
||||
ap_sta_clear_disconnect_timeouts(hapd, sta);
|
||||
|
||||
/* IEEE 802.11F (IAPP) */
|
||||
if (hapd->conf->ieee802_11f)
|
||||
iapp_new_station(hapd->iapp, sta);
|
||||
|
||||
#ifdef CONFIG_P2P
|
||||
if (sta->p2p_ie == NULL && !sta->no_p2p_set) {
|
||||
sta->no_p2p_set = 1;
|
||||
|
|
|
@ -179,8 +179,6 @@ struct hostapd_data {
|
|||
u64 acct_session_id;
|
||||
struct radius_das_data *radius_das;
|
||||
|
||||
struct iapp_data *iapp;
|
||||
|
||||
struct hostapd_cached_radius_acl *acl_cache;
|
||||
struct hostapd_acl_query_data *acl_queries;
|
||||
|
||||
|
|
542
src/ap/iapp.c
542
src/ap/iapp.c
|
@ -1,542 +0,0 @@
|
|||
/*
|
||||
* hostapd / IEEE 802.11F-2003 Inter-Access Point Protocol (IAPP)
|
||||
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*
|
||||
* Note: IEEE 802.11F-2003 was a experimental use specification. It has expired
|
||||
* and IEEE has withdrawn it. In other words, it is likely better to look at
|
||||
* using some other mechanism for AP-to-AP communication than extending the
|
||||
* implementation here.
|
||||
*/
|
||||
|
||||
/* TODO:
|
||||
* Level 1: no administrative or security support
|
||||
* (e.g., static BSSID to IP address mapping in each AP)
|
||||
* Level 2: support for dynamic mapping of BSSID to IP address
|
||||
* Level 3: support for encryption and authentication of IAPP messages
|
||||
* - add support for MOVE-notify and MOVE-response (this requires support for
|
||||
* finding out IP address for previous AP using RADIUS)
|
||||
* - add support for Send- and ACK-Security-Block to speedup IEEE 802.1X during
|
||||
* reassociation to another AP
|
||||
* - implement counters etc. for IAPP MIB
|
||||
* - verify endianness of fields in IAPP messages; are they big-endian as
|
||||
* used here?
|
||||
* - RADIUS connection for AP registration and BSSID to IP address mapping
|
||||
* - TCP connection for IAPP MOVE, CACHE
|
||||
* - broadcast ESP for IAPP ADD-notify
|
||||
* - ESP for IAPP MOVE messages
|
||||
* - security block sending/processing
|
||||
* - IEEE 802.11 context transfer
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netpacket/packet.h>
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "hostapd.h"
|
||||
#include "ap_config.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "sta_info.h"
|
||||
#include "iapp.h"
|
||||
|
||||
|
||||
#define IAPP_MULTICAST "224.0.1.178"
|
||||
#define IAPP_UDP_PORT 3517
|
||||
#define IAPP_TCP_PORT 3517
|
||||
|
||||
struct iapp_hdr {
|
||||
u8 version;
|
||||
u8 command;
|
||||
be16 identifier;
|
||||
be16 length;
|
||||
/* followed by length-6 octets of data */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define IAPP_VERSION 0
|
||||
|
||||
enum IAPP_COMMAND {
|
||||
IAPP_CMD_ADD_notify = 0,
|
||||
IAPP_CMD_MOVE_notify = 1,
|
||||
IAPP_CMD_MOVE_response = 2,
|
||||
IAPP_CMD_Send_Security_Block = 3,
|
||||
IAPP_CMD_ACK_Security_Block = 4,
|
||||
IAPP_CMD_CACHE_notify = 5,
|
||||
IAPP_CMD_CACHE_response = 6,
|
||||
};
|
||||
|
||||
|
||||
/* ADD-notify - multicast UDP on the local LAN */
|
||||
struct iapp_add_notify {
|
||||
u8 addr_len; /* ETH_ALEN */
|
||||
u8 reserved;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
be16 seq_num;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
|
||||
struct iapp_layer2_update {
|
||||
u8 da[ETH_ALEN]; /* broadcast */
|
||||
u8 sa[ETH_ALEN]; /* STA addr */
|
||||
be16 len; /* 6 */
|
||||
u8 dsap; /* null DSAP address */
|
||||
u8 ssap; /* null SSAP address, CR=Response */
|
||||
u8 control;
|
||||
u8 xid_info[3];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* MOVE-notify - unicast TCP */
|
||||
struct iapp_move_notify {
|
||||
u8 addr_len; /* ETH_ALEN */
|
||||
u8 reserved;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u16 seq_num;
|
||||
u16 ctx_block_len;
|
||||
/* followed by ctx_block_len bytes */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* MOVE-response - unicast TCP */
|
||||
struct iapp_move_response {
|
||||
u8 addr_len; /* ETH_ALEN */
|
||||
u8 status;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u16 seq_num;
|
||||
u16 ctx_block_len;
|
||||
/* followed by ctx_block_len bytes */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum {
|
||||
IAPP_MOVE_SUCCESSFUL = 0,
|
||||
IAPP_MOVE_DENIED = 1,
|
||||
IAPP_MOVE_STALE_MOVE = 2,
|
||||
};
|
||||
|
||||
|
||||
/* CACHE-notify */
|
||||
struct iapp_cache_notify {
|
||||
u8 addr_len; /* ETH_ALEN */
|
||||
u8 reserved;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u16 seq_num;
|
||||
u8 current_ap[ETH_ALEN];
|
||||
u16 ctx_block_len;
|
||||
/* ctx_block_len bytes of context block followed by 16-bit context
|
||||
* timeout */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* CACHE-response - unicast TCP */
|
||||
struct iapp_cache_response {
|
||||
u8 addr_len; /* ETH_ALEN */
|
||||
u8 status;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u16 seq_num;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum {
|
||||
IAPP_CACHE_SUCCESSFUL = 0,
|
||||
IAPP_CACHE_STALE_CACHE = 1,
|
||||
};
|
||||
|
||||
|
||||
/* Send-Security-Block - unicast TCP */
|
||||
struct iapp_send_security_block {
|
||||
u8 iv[8];
|
||||
u16 sec_block_len;
|
||||
/* followed by sec_block_len bytes of security block */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* ACK-Security-Block - unicast TCP */
|
||||
struct iapp_ack_security_block {
|
||||
u8 iv[8];
|
||||
u8 new_ap_ack_authenticator[48];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct iapp_data {
|
||||
struct hostapd_data *hapd;
|
||||
u16 identifier; /* next IAPP identifier */
|
||||
struct in_addr own, multicast;
|
||||
int udp_sock;
|
||||
int packet_sock;
|
||||
};
|
||||
|
||||
|
||||
static void iapp_send_add(struct iapp_data *iapp, u8 *mac_addr, u16 seq_num)
|
||||
{
|
||||
char buf[128];
|
||||
struct iapp_hdr *hdr;
|
||||
struct iapp_add_notify *add;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
/* Send IAPP ADD-notify to remove possible association from other APs
|
||||
*/
|
||||
|
||||
hdr = (struct iapp_hdr *) buf;
|
||||
hdr->version = IAPP_VERSION;
|
||||
hdr->command = IAPP_CMD_ADD_notify;
|
||||
hdr->identifier = host_to_be16(iapp->identifier++);
|
||||
hdr->length = host_to_be16(sizeof(*hdr) + sizeof(*add));
|
||||
|
||||
add = (struct iapp_add_notify *) (hdr + 1);
|
||||
add->addr_len = ETH_ALEN;
|
||||
add->reserved = 0;
|
||||
os_memcpy(add->mac_addr, mac_addr, ETH_ALEN);
|
||||
|
||||
add->seq_num = host_to_be16(seq_num);
|
||||
|
||||
os_memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = iapp->multicast.s_addr;
|
||||
addr.sin_port = htons(IAPP_UDP_PORT);
|
||||
if (sendto(iapp->udp_sock, buf, (char *) (add + 1) - buf, 0,
|
||||
(struct sockaddr *) &addr, sizeof(addr)) < 0)
|
||||
wpa_printf(MSG_INFO, "sendto[IAPP-ADD]: %s", strerror(errno));
|
||||
}
|
||||
|
||||
|
||||
static void iapp_send_layer2_update(struct iapp_data *iapp, u8 *addr)
|
||||
{
|
||||
struct iapp_layer2_update msg;
|
||||
|
||||
/* Send Level 2 Update Frame to update forwarding tables in layer 2
|
||||
* bridge devices */
|
||||
|
||||
/* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
|
||||
* Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
|
||||
|
||||
os_memset(msg.da, 0xff, ETH_ALEN);
|
||||
os_memcpy(msg.sa, addr, ETH_ALEN);
|
||||
msg.len = host_to_be16(6);
|
||||
msg.dsap = 0; /* NULL DSAP address */
|
||||
msg.ssap = 0x01; /* NULL SSAP address, CR Bit: Response */
|
||||
msg.control = 0xaf; /* XID response lsb.1111F101.
|
||||
* F=0 (no poll command; unsolicited frame) */
|
||||
msg.xid_info[0] = 0x81; /* XID format identifier */
|
||||
msg.xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */
|
||||
msg.xid_info[2] = 1 << 1; /* XID sender's receive window size (RW)
|
||||
* FIX: what is correct RW with 802.11? */
|
||||
|
||||
if (send(iapp->packet_sock, &msg, sizeof(msg), 0) < 0)
|
||||
wpa_printf(MSG_INFO, "send[L2 Update]: %s", strerror(errno));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* iapp_new_station - IAPP processing for a new STA
|
||||
* @iapp: IAPP data
|
||||
* @sta: The associated station
|
||||
*/
|
||||
void iapp_new_station(struct iapp_data *iapp, struct sta_info *sta)
|
||||
{
|
||||
u16 seq = 0; /* TODO */
|
||||
|
||||
if (iapp == NULL)
|
||||
return;
|
||||
|
||||
/* IAPP-ADD.request(MAC Address, Sequence Number, Timeout) */
|
||||
hostapd_logger(iapp->hapd, sta->addr, HOSTAPD_MODULE_IAPP,
|
||||
HOSTAPD_LEVEL_DEBUG, "IAPP-ADD.request(seq=%d)", seq);
|
||||
iapp_send_layer2_update(iapp, sta->addr);
|
||||
iapp_send_add(iapp, sta->addr, seq);
|
||||
|
||||
/* TODO: If this was reassociation:
|
||||
* IAPP-MOVE.request(MAC Address, Sequence Number, Old AP,
|
||||
* Context Block, Timeout)
|
||||
* TODO: Send IAPP-MOVE to the old AP; Map Old AP BSSID to
|
||||
* IP address */
|
||||
}
|
||||
|
||||
|
||||
static void iapp_process_add_notify(struct iapp_data *iapp,
|
||||
struct sockaddr_in *from,
|
||||
struct iapp_hdr *hdr, int len)
|
||||
{
|
||||
struct iapp_add_notify *add = (struct iapp_add_notify *) (hdr + 1);
|
||||
struct sta_info *sta;
|
||||
|
||||
if (len != sizeof(*add)) {
|
||||
wpa_printf(MSG_INFO, "Invalid IAPP-ADD packet length %d (expected %lu)",
|
||||
len, (unsigned long) sizeof(*add));
|
||||
return;
|
||||
}
|
||||
|
||||
sta = ap_get_sta(iapp->hapd, add->mac_addr);
|
||||
|
||||
/* IAPP-ADD.indication(MAC Address, Sequence Number) */
|
||||
hostapd_logger(iapp->hapd, add->mac_addr, HOSTAPD_MODULE_IAPP,
|
||||
HOSTAPD_LEVEL_INFO,
|
||||
"Received IAPP ADD-notify (seq# %d) from %s:%d%s",
|
||||
be_to_host16(add->seq_num),
|
||||
inet_ntoa(from->sin_addr), ntohs(from->sin_port),
|
||||
sta ? "" : " (STA not found)");
|
||||
|
||||
if (!sta)
|
||||
return;
|
||||
|
||||
/* TODO: could use seq_num to try to determine whether last association
|
||||
* to this AP is newer than the one advertised in IAPP-ADD. Although,
|
||||
* this is not really a reliable verification. */
|
||||
|
||||
hostapd_logger(iapp->hapd, add->mac_addr, HOSTAPD_MODULE_IAPP,
|
||||
HOSTAPD_LEVEL_DEBUG,
|
||||
"Removing STA due to IAPP ADD-notify");
|
||||
ap_sta_disconnect(iapp->hapd, sta, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* iapp_receive_udp - Process IAPP UDP frames
|
||||
* @sock: File descriptor for the socket
|
||||
* @eloop_ctx: IAPP data (struct iapp_data *)
|
||||
* @sock_ctx: Not used
|
||||
*/
|
||||
static void iapp_receive_udp(int sock, void *eloop_ctx, void *sock_ctx)
|
||||
{
|
||||
struct iapp_data *iapp = eloop_ctx;
|
||||
int len, hlen;
|
||||
unsigned char buf[128];
|
||||
struct sockaddr_in from;
|
||||
socklen_t fromlen;
|
||||
struct iapp_hdr *hdr;
|
||||
|
||||
/* Handle incoming IAPP frames (over UDP/IP) */
|
||||
|
||||
fromlen = sizeof(from);
|
||||
len = recvfrom(iapp->udp_sock, buf, sizeof(buf), 0,
|
||||
(struct sockaddr *) &from, &fromlen);
|
||||
if (len < 0) {
|
||||
wpa_printf(MSG_INFO, "iapp_receive_udp - recvfrom: %s",
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if (from.sin_addr.s_addr == iapp->own.s_addr)
|
||||
return; /* ignore own IAPP messages */
|
||||
|
||||
hostapd_logger(iapp->hapd, NULL, HOSTAPD_MODULE_IAPP,
|
||||
HOSTAPD_LEVEL_DEBUG,
|
||||
"Received %d byte IAPP frame from %s%s\n",
|
||||
len, inet_ntoa(from.sin_addr),
|
||||
len < (int) sizeof(*hdr) ? " (too short)" : "");
|
||||
|
||||
if (len < (int) sizeof(*hdr))
|
||||
return;
|
||||
|
||||
hdr = (struct iapp_hdr *) buf;
|
||||
hlen = be_to_host16(hdr->length);
|
||||
hostapd_logger(iapp->hapd, NULL, HOSTAPD_MODULE_IAPP,
|
||||
HOSTAPD_LEVEL_DEBUG,
|
||||
"RX: version=%d command=%d id=%d len=%d\n",
|
||||
hdr->version, hdr->command,
|
||||
be_to_host16(hdr->identifier), hlen);
|
||||
if (hdr->version != IAPP_VERSION) {
|
||||
wpa_printf(MSG_INFO, "Dropping IAPP frame with unknown version %d",
|
||||
hdr->version);
|
||||
return;
|
||||
}
|
||||
if (hlen > len) {
|
||||
wpa_printf(MSG_INFO, "Underflow IAPP frame (hlen=%d len=%d)",
|
||||
hlen, len);
|
||||
return;
|
||||
}
|
||||
if (hlen < len) {
|
||||
wpa_printf(MSG_INFO, "Ignoring %d extra bytes from IAPP frame",
|
||||
len - hlen);
|
||||
len = hlen;
|
||||
}
|
||||
|
||||
switch (hdr->command) {
|
||||
case IAPP_CMD_ADD_notify:
|
||||
iapp_process_add_notify(iapp, &from, hdr, len - sizeof(*hdr));
|
||||
break;
|
||||
case IAPP_CMD_MOVE_notify:
|
||||
/* TODO: MOVE is using TCP; so move this to TCP handler once it
|
||||
* is implemented.. */
|
||||
/* IAPP-MOVE.indication(MAC Address, New BSSID,
|
||||
* Sequence Number, AP Address, Context Block) */
|
||||
/* TODO: process */
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_INFO, "Unknown IAPP command %d", hdr->command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_ll addr;
|
||||
int ifindex;
|
||||
struct sockaddr_in *paddr, uaddr;
|
||||
struct iapp_data *iapp;
|
||||
struct ip_mreqn mreq;
|
||||
int reuseaddr = 1;
|
||||
|
||||
iapp = os_zalloc(sizeof(*iapp));
|
||||
if (iapp == NULL)
|
||||
return NULL;
|
||||
iapp->hapd = hapd;
|
||||
iapp->udp_sock = iapp->packet_sock = -1;
|
||||
|
||||
/* TODO:
|
||||
* open socket for sending and receiving IAPP frames over TCP
|
||||
*/
|
||||
|
||||
iapp->udp_sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (iapp->udp_sock < 0) {
|
||||
wpa_printf(MSG_INFO, "iapp_init - socket[PF_INET,SOCK_DGRAM]: %s",
|
||||
strerror(errno));
|
||||
iapp_deinit(iapp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
|
||||
if (ioctl(iapp->udp_sock, SIOCGIFINDEX, &ifr) != 0) {
|
||||
wpa_printf(MSG_INFO, "iapp_init - ioctl(SIOCGIFINDEX): %s",
|
||||
strerror(errno));
|
||||
iapp_deinit(iapp);
|
||||
return NULL;
|
||||
}
|
||||
ifindex = ifr.ifr_ifindex;
|
||||
|
||||
if (ioctl(iapp->udp_sock, SIOCGIFADDR, &ifr) != 0) {
|
||||
wpa_printf(MSG_INFO, "iapp_init - ioctl(SIOCGIFADDR): %s",
|
||||
strerror(errno));
|
||||
iapp_deinit(iapp);
|
||||
return NULL;
|
||||
}
|
||||
paddr = (struct sockaddr_in *) &ifr.ifr_addr;
|
||||
if (paddr->sin_family != AF_INET) {
|
||||
wpa_printf(MSG_INFO, "IAPP: Invalid address family %i (SIOCGIFADDR)",
|
||||
paddr->sin_family);
|
||||
iapp_deinit(iapp);
|
||||
return NULL;
|
||||
}
|
||||
iapp->own.s_addr = paddr->sin_addr.s_addr;
|
||||
|
||||
if (ioctl(iapp->udp_sock, SIOCGIFBRDADDR, &ifr) != 0) {
|
||||
wpa_printf(MSG_INFO, "iapp_init - ioctl(SIOCGIFBRDADDR): %s",
|
||||
strerror(errno));
|
||||
iapp_deinit(iapp);
|
||||
return NULL;
|
||||
}
|
||||
paddr = (struct sockaddr_in *) &ifr.ifr_addr;
|
||||
if (paddr->sin_family != AF_INET) {
|
||||
wpa_printf(MSG_INFO, "Invalid address family %i (SIOCGIFBRDADDR)",
|
||||
paddr->sin_family);
|
||||
iapp_deinit(iapp);
|
||||
return NULL;
|
||||
}
|
||||
inet_aton(IAPP_MULTICAST, &iapp->multicast);
|
||||
|
||||
os_memset(&uaddr, 0, sizeof(uaddr));
|
||||
uaddr.sin_family = AF_INET;
|
||||
uaddr.sin_port = htons(IAPP_UDP_PORT);
|
||||
|
||||
if (setsockopt(iapp->udp_sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
|
||||
sizeof(reuseaddr)) < 0) {
|
||||
wpa_printf(MSG_INFO,
|
||||
"iapp_init - setsockopt[UDP,SO_REUSEADDR]: %s",
|
||||
strerror(errno));
|
||||
/*
|
||||
* Ignore this and try to continue. This is fine for single
|
||||
* BSS cases, but may fail if multiple BSSes enable IAPP.
|
||||
*/
|
||||
}
|
||||
|
||||
if (bind(iapp->udp_sock, (struct sockaddr *) &uaddr,
|
||||
sizeof(uaddr)) < 0) {
|
||||
wpa_printf(MSG_INFO, "iapp_init - bind[UDP]: %s",
|
||||
strerror(errno));
|
||||
iapp_deinit(iapp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_memset(&mreq, 0, sizeof(mreq));
|
||||
mreq.imr_multiaddr = iapp->multicast;
|
||||
mreq.imr_address.s_addr = INADDR_ANY;
|
||||
mreq.imr_ifindex = 0;
|
||||
if (setsockopt(iapp->udp_sock, SOL_IP, IP_ADD_MEMBERSHIP, &mreq,
|
||||
sizeof(mreq)) < 0) {
|
||||
wpa_printf(MSG_INFO, "iapp_init - setsockopt[UDP,IP_ADD_MEMBERSHIP]: %s",
|
||||
strerror(errno));
|
||||
iapp_deinit(iapp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iapp->packet_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||
if (iapp->packet_sock < 0) {
|
||||
wpa_printf(MSG_INFO, "iapp_init - socket[PF_PACKET,SOCK_RAW]: %s",
|
||||
strerror(errno));
|
||||
iapp_deinit(iapp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_memset(&addr, 0, sizeof(addr));
|
||||
addr.sll_family = AF_PACKET;
|
||||
addr.sll_ifindex = ifindex;
|
||||
if (bind(iapp->packet_sock, (struct sockaddr *) &addr,
|
||||
sizeof(addr)) < 0) {
|
||||
wpa_printf(MSG_INFO, "iapp_init - bind[PACKET]: %s",
|
||||
strerror(errno));
|
||||
iapp_deinit(iapp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (eloop_register_read_sock(iapp->udp_sock, iapp_receive_udp,
|
||||
iapp, NULL)) {
|
||||
wpa_printf(MSG_INFO, "Could not register read socket for IAPP");
|
||||
iapp_deinit(iapp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_INFO, "IEEE 802.11F (IAPP) using interface %s", iface);
|
||||
|
||||
/* TODO: For levels 2 and 3: send RADIUS Initiate-Request, receive
|
||||
* RADIUS Initiate-Accept or Initiate-Reject. IAPP port should actually
|
||||
* be openned only after receiving Initiate-Accept. If Initiate-Reject
|
||||
* is received, IAPP is not started. */
|
||||
|
||||
return iapp;
|
||||
}
|
||||
|
||||
|
||||
void iapp_deinit(struct iapp_data *iapp)
|
||||
{
|
||||
struct ip_mreqn mreq;
|
||||
|
||||
if (iapp == NULL)
|
||||
return;
|
||||
|
||||
if (iapp->udp_sock >= 0) {
|
||||
os_memset(&mreq, 0, sizeof(mreq));
|
||||
mreq.imr_multiaddr = iapp->multicast;
|
||||
mreq.imr_address.s_addr = INADDR_ANY;
|
||||
mreq.imr_ifindex = 0;
|
||||
if (setsockopt(iapp->udp_sock, SOL_IP, IP_DROP_MEMBERSHIP,
|
||||
&mreq, sizeof(mreq)) < 0) {
|
||||
wpa_printf(MSG_INFO, "iapp_deinit - setsockopt[UDP,IP_DEL_MEMBERSHIP]: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
eloop_unregister_read_sock(iapp->udp_sock);
|
||||
close(iapp->udp_sock);
|
||||
}
|
||||
if (iapp->packet_sock >= 0) {
|
||||
eloop_unregister_read_sock(iapp->packet_sock);
|
||||
close(iapp->packet_sock);
|
||||
}
|
||||
os_free(iapp);
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* hostapd / IEEE 802.11F-2003 Inter-Access Point Protocol (IAPP)
|
||||
* Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef IAPP_H
|
||||
#define IAPP_H
|
||||
|
||||
struct iapp_data;
|
||||
|
||||
#ifdef CONFIG_IAPP
|
||||
|
||||
void iapp_new_station(struct iapp_data *iapp, struct sta_info *sta);
|
||||
struct iapp_data * iapp_init(struct hostapd_data *hapd, const char *iface);
|
||||
void iapp_deinit(struct iapp_data *iapp);
|
||||
|
||||
#else /* CONFIG_IAPP */
|
||||
|
||||
static inline void iapp_new_station(struct iapp_data *iapp,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct iapp_data * iapp_init(struct hostapd_data *hapd,
|
||||
const char *iface)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void iapp_deinit(struct iapp_data *iapp)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IAPP */
|
||||
|
||||
#endif /* IAPP_H */
|
|
@ -305,7 +305,6 @@ void hostapd_logger_register_cb(hostapd_logger_cb_func func);
|
|||
#define HOSTAPD_MODULE_RADIUS 0x00000004
|
||||
#define HOSTAPD_MODULE_WPA 0x00000008
|
||||
#define HOSTAPD_MODULE_DRIVER 0x00000010
|
||||
#define HOSTAPD_MODULE_IAPP 0x00000020
|
||||
#define HOSTAPD_MODULE_MLME 0x00000040
|
||||
|
||||
enum hostapd_logger_level {
|
||||
|
|
|
@ -80,7 +80,6 @@ CONFIG_MBO=y
|
|||
CONFIG_CODE_COVERAGE=y
|
||||
CFLAGS += -O0 -Wsign-compare
|
||||
|
||||
CONFIG_IAPP=y
|
||||
CONFIG_TAXONOMY=y
|
||||
#CONFIG_FILS=y
|
||||
#CONFIG_FILS_SK_PFS=y
|
||||
|
|
|
@ -105,7 +105,6 @@ CONFIG_SUITEB=y
|
|||
#LIBS_c += -fsanitize=undefined
|
||||
CONFIG_MBO=y
|
||||
|
||||
CONFIG_IAPP=y
|
||||
CONFIG_TAXONOMY=y
|
||||
CONFIG_FILS=y
|
||||
CONFIG_FILS_SK_PFS=y
|
||||
|
|
Loading…
Reference in a new issue