Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes in HOSTAPD to Support PAC #90

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/ap/ap_drv_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,4 +391,15 @@ hostapd_drv_set_band(struct hostapd_data *hapd, enum set_band band)
return hapd->driver->set_band(hapd->drv_priv, band);
}

#ifdef CONFIG_SONIC_HOSTAPD
static inline int
hostapd_drv_auth_resp_send(struct hostapd_data *hapd, char *intf, u8 *addr,
char *status, void *param)
{
if (!hapd->driver || !hapd->driver->auth_resp_send)
return -1;
return hapd->driver->auth_resp_send(intf, addr, status, param);
}
#endif

#endif /* AP_DRV_OPS */
47 changes: 46 additions & 1 deletion src/ap/hostapd.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,10 @@ static void hostapd_clear_old(struct hostapd_iface *iface)
* allow them to use the BSS anymore.
*/
for (j = 0; j < iface->num_bss; j++) {
#ifndef CONFIG_SONIC_HOSTAPD

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The design mentions that the hostapd receive packets directly when the mode is configured as MAB. Can you please help with the APIs for that functionality?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I didn't get the question. The hostapd doesn't or never communicates with MAB directly. It communicates only with PACD. Similarly MAB communicates only with PACD. Can you please point to the section in the design document, if it is mentioned.. will correct the same.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry my bad. Somehow I remember seeing that & wanted to check

hostapd_flush_old_stations(iface->bss[j],
WLAN_REASON_PREV_AUTH_NOT_VALID);
#endif
#ifdef CONFIG_WEP
hostapd_broadcast_wep_clear(iface->bss[j]);
#endif /* CONFIG_WEP */
Expand All @@ -186,6 +188,11 @@ static void hostapd_clear_old(struct hostapd_iface *iface)
/* TODO: update dynamic data based on changed configuration
* items (e.g., open/close sockets, etc.) */
radius_client_flush(iface->bss[j]->radius, 0);
#ifdef CONFIG_SONIC_HOSTAPD
radius_close_auth_sockets(iface->bss[j]->radius);
radius_close_acct_sockets(iface->bss[j]->radius);
#endif

#endif /* CONFIG_NO_RADIUS */
}
}
Expand Down Expand Up @@ -2163,6 +2170,17 @@ static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,

for (j = 0; j < iface->num_bss; j++)
hostapd_neighbor_set_own_report(iface->bss[j]);

#ifdef CONFIG_SONIC_HOSTAPD
#ifdef HOSTAPD
if (hapd->driver->auth_resp_send)
{
wpa_printf(MSG_DEBUG, "%s: Informing PAC - method_change - enable.",
iface->bss[0]->conf->iface);
hapd->driver->auth_resp_send(hapd->conf->iface, NULL, "method_change", (void *)"enable");
}
#endif
#endif

return 0;

Expand Down Expand Up @@ -2213,6 +2231,18 @@ int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)

if (err) {
wpa_printf(MSG_ERROR, "Interface initialization failed");

#ifdef CONFIG_SONIC_HOSTAPD
#ifdef HOSTAPD
if (hapd->driver->auth_resp_send)
{
wpa_printf(MSG_DEBUG, "%s: Error occured. Informing PAC - method_change - disable.",
iface->bss[0]->conf->iface);
hapd->driver->auth_resp_send(iface->bss[0]->conf->iface, NULL, "method_change", (void *)"disable");
}
#endif
#endif

hostapd_set_state(iface, HAPD_IFACE_DISABLED);
iface->need_to_start_in_sync = 0;
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
Expand Down Expand Up @@ -2651,8 +2681,11 @@ void hostapd_interface_deinit_free(struct hostapd_iface *iface)
hostapd_interface_free(iface);
}


#ifdef CONFIG_SONIC_HOSTAPD
void hostapd_deinit_driver(const struct wpa_driver_ops *driver,
#else
static void hostapd_deinit_driver(const struct wpa_driver_ops *driver,
#endif
void *drv_priv,
struct hostapd_iface *hapd_iface)
{
Expand Down Expand Up @@ -2777,6 +2810,18 @@ int hostapd_disable_iface(struct hostapd_iface *hapd_iface)

wpa_printf(MSG_DEBUG, "Interface %s disabled",
hapd_iface->bss[0]->conf->iface);

#ifdef CONFIG_SONIC_HOSTAPD
#ifdef HOSTAPD
if (driver->auth_resp_send)
{
wpa_printf(MSG_DEBUG, "%s: Informing PAC - method_change - disable.",
hapd_iface->bss[0]->conf->iface);
driver->auth_resp_send(hapd_iface->bss[0]->conf->iface, NULL, "method_change", (void *)"disable");
}
#endif
#endif

hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED);
return 0;
}
Expand Down
6 changes: 6 additions & 0 deletions src/ap/sta_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
#include "vlan.h"
#include "common/wpa_common.h"
#include "common/ieee802_11_defs.h"
#ifdef CONFIG_SONIC_RADIUS
#include "radius/radius_attr_parse.h"
#endif

/* STA flags */
#define WLAN_STA_AUTH BIT(0)
Expand Down Expand Up @@ -286,6 +289,9 @@ struct sta_info {
unsigned int airtime_weight;
struct os_reltime backlogged_until;
#endif /* CONFIG_AIRTIME_POLICY */
#ifdef CONFIG_SONIC_RADIUS
attrInfo_t attr_info;
#endif
};


Expand Down
12 changes: 12 additions & 0 deletions src/drivers/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -4464,6 +4464,18 @@ struct wpa_driver_ops {
* explicitly allow reception of broadcast Public Action frames.
*/
int (*dpp_listen)(void *priv, bool enable);

#ifdef CONFIG_SONIC_HOSTAPD
/**
* auth_resp_send - send status to PAC
* @intf: interface
* @addr: station mac address
* @status: reply status
* @param: status parameters
* Returns: 0 on success, -1 on failure
* */
int (*auth_resp_send)(char *intf, u8 *addr, char *status, void *param);
#endif
};

/**
Expand Down
106 changes: 91 additions & 15 deletions src/drivers/driver_wired.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
#include "eloop.h"
#include "driver.h"
#include "driver_wired_common.h"
#include "common/eapol_common.h"
#ifdef CONFIG_SONIC_HOSTAPD
#ifdef HOSTAPD
#include "ap/hostapd.h"
#include "ap/sta_info.h"
#endif
#endif

#include <sys/ioctl.h>
#undef IFNAMSIZ
Expand All @@ -33,21 +40,20 @@
#pragma pack(push, 1)
#endif /* _MSC_VER */

struct ieee8023_hdr {
u8 dest[6];
u8 src[6];
u16 ethertype;
} STRUCT_PACKED;

#ifdef _MSC_VER
#pragma pack(pop)
#endif /* _MSC_VER */

#ifdef HOSTAPD
extern int wired_driver_auth_resp_send(char *intf, u8 *addr, char *status, void *param);
#endif

struct wpa_driver_wired_data {
struct driver_wired_common_data common;

#ifndef CONFIG_SONIC_HOSTAPD
int dhcp_sock; /* socket for dhcp packets */
#endif
int use_pae_group_addr;
};

Expand Down Expand Up @@ -84,6 +90,9 @@ static void handle_data(void *ctx, unsigned char *buf, size_t len)
u8 *pos, *sa;
size_t left;
union wpa_event_data event;
struct sta_info *sta = NULL;
struct hostapd_data *hapd = ctx;
struct ieee802_1x_hdr *hdr_802_1x = NULL;

/* must contain at least ieee8023_hdr 6 byte source, 6 byte dest,
* 2 byte ethertype */
Expand All @@ -98,6 +107,51 @@ static void handle_data(void *ctx, unsigned char *buf, size_t len)
switch (ntohs(hdr->ethertype)) {
case ETH_P_PAE:
wpa_printf(MSG_MSGDUMP, "Received EAPOL packet");

if (hapd->driver->auth_resp_send)
{
hostapd_logger(hapd, hdr->src, HOSTAPD_MODULE_IEEE8021X,
HOSTAPD_LEVEL_DEBUG,
"Received EAPOL packet. Get the associated station");

sta = ap_get_sta(hapd, hdr->src);

pos = (u8 *) (hdr + 1);
hdr_802_1x = (struct ieee802_1x_hdr *)pos;

if (!sta){
if (IEEE802_1X_TYPE_EAPOL_START == hdr_802_1x->type) {

/* Inform PAC */
hostapd_logger(hapd, hdr->src, HOSTAPD_MODULE_IEEE8021X,
HOSTAPD_LEVEL_DEBUG,
"Received EAPOL START packet. Informing PAC");
hapd->driver->auth_resp_send(hapd->conf->iface, hdr->src, "new_client", NULL);
}
else if (IEEE802_1X_TYPE_EAPOL_LOGOFF == hdr_802_1x->type)
{
/* Inform PAC */
hostapd_logger(hapd, hdr->src, HOSTAPD_MODULE_IEEE8021X,
HOSTAPD_LEVEL_DEBUG,
"Received EAPOL LOGOFF packet. Informing PAC");

hapd->driver->auth_resp_send(hapd->conf->iface, hdr->src, "client_disconnected", NULL);
}
return;
}

/* check if the client is getting de-authenticated.
if yes, then ignore any triggers during this state */

if (sta->flags & WLAN_STA_PENDING_DEAUTH_CB)
{
hostapd_logger(hapd, hdr->src, HOSTAPD_MODULE_IEEE8021X,
HOSTAPD_LEVEL_DEBUG,
"Received EAPOL packet of type %d while client is getting de-authenticated. Ignoring EAPOL packet", hdr_802_1x->type);
return;
}
}

sa = hdr->src;
os_memset(&event, 0, sizeof(event));
event.new_sta.addr = sa;
Expand Down Expand Up @@ -131,7 +185,7 @@ static void handle_read(int sock, void *eloop_ctx, void *sock_ctx)
handle_data(eloop_ctx, buf, len);
}


#ifndef CONFIG_SONIC_HOSTAPD
static void handle_dhcp(int sock, void *eloop_ctx, void *sock_ctx)
{
int len;
Expand Down Expand Up @@ -162,6 +216,7 @@ static void handle_dhcp(int sock, void *eloop_ctx, void *sock_ctx)
event.new_sta.addr = mac_address;
wpa_supplicant_event(eloop_ctx, EVENT_NEW_STA, &event);
}
#endif
#endif /* __linux__ */


Expand All @@ -170,8 +225,15 @@ static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr)
#ifdef __linux__
struct ifreq ifr;
struct sockaddr_ll addr;

#ifndef CONFIG_SONIC_HOSTAPD
struct sockaddr_in addr2;
int n = 1;
#endif

#define SOCK_RCV_BUF_LEN (1024 * 1024)

int recv_buf_len = SOCK_RCV_BUF_LEN;

drv->common.sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_PAE));
if (drv->common.sock < 0) {
Expand All @@ -180,12 +242,21 @@ static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr)
return -1;
}

if (setsockopt(drv->common.sock, SOL_SOCKET, SO_RCVBUF, &recv_buf_len, sizeof(recv_buf_len)) == -1)
{
wpa_printf(MSG_INFO, "Could not set the read socket buffer size");
close(drv->common.sock);
return -1;
}

if (eloop_register_read_sock(drv->common.sock, handle_read,
drv->common.ctx, NULL)) {
wpa_printf(MSG_INFO, "Could not register read socket");
return -1;
}

wpa_printf(MSG_DEBUG, "Getting the ifindex for interface %s",
drv->common.ifname);
os_memset(&ifr, 0, sizeof(ifr));
os_strlcpy(ifr.ifr_name, drv->common.ifname, sizeof(ifr.ifr_name));
if (ioctl(drv->common.sock, SIOCGIFINDEX, &ifr) != 0) {
Expand Down Expand Up @@ -229,6 +300,7 @@ static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr)
}
os_memcpy(own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);

#ifndef CONFIG_SONIC_HOSTAPD
/* setup dhcp listen socket for sta detection */
if ((drv->dhcp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
wpa_printf(MSG_ERROR, "socket call failed for dhcp: %s",
Expand Down Expand Up @@ -275,7 +347,7 @@ static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr)
wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
return -1;
}

#endif
return 0;
#else /* __linux__ */
return -1;
Expand Down Expand Up @@ -322,7 +394,6 @@ static int wired_send_eapol(void *priv, const u8 *addr,
return res;
}


static void * wired_driver_hapd_init(struct hostapd_data *hapd,
struct wpa_init_params *params)
{
Expand All @@ -338,17 +409,19 @@ static void * wired_driver_hapd_init(struct hostapd_data *hapd,
drv->common.ctx = hapd;
os_strlcpy(drv->common.ifname, params->ifname,
sizeof(drv->common.ifname));
wpa_printf(MSG_INFO,
"drv->common.ifname received is %s", drv->common.ifname);

drv->use_pae_group_addr = params->use_pae_group_addr;

if (wired_init_sockets(drv, params->own_addr)) {
os_free(drv);
return NULL;
}

return drv;
}


static void wired_driver_hapd_deinit(void *priv)
{
struct wpa_driver_wired_data *drv = priv;
Expand All @@ -357,12 +430,13 @@ static void wired_driver_hapd_deinit(void *priv)
eloop_unregister_read_sock(drv->common.sock);
close(drv->common.sock);
}

#ifndef CONFIG_SONIC_HOSTAPD
if (drv->dhcp_sock >= 0) {
eloop_unregister_read_sock(drv->dhcp_sock);
close(drv->dhcp_sock);
}

#endif

os_free(drv);
}

Expand Down Expand Up @@ -392,7 +466,6 @@ static void wpa_driver_wired_deinit(void *priv)
os_free(drv);
}


const struct wpa_driver_ops wpa_driver_wired_ops = {
.name = "wired",
.desc = "Wired Ethernet driver",
Expand All @@ -402,6 +475,9 @@ const struct wpa_driver_ops wpa_driver_wired_ops = {
.get_ssid = driver_wired_get_ssid,
.get_bssid = driver_wired_get_bssid,
.get_capa = driver_wired_get_capa,
.init = wpa_driver_wired_init,
#ifdef HOSTAPD
.auth_resp_send = wired_driver_auth_resp_send,
#endif
.init = wpa_driver_wired_init,
.deinit = wpa_driver_wired_deinit,
};
4 changes: 4 additions & 0 deletions src/drivers/drivers.mak
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ DRV_OBJS += ../src/drivers/driver_wired.o
NEED_DRV_WIRED_COMMON=1
endif

ifdef CONFIG_SONIC_HOSTAPD
DRV_OBJS += ../src/drivers/driver_wired_sonic.o
endif

ifdef CONFIG_DRIVER_MACSEC_SONIC
DRV_CFLAGS += -DCONFIG_DRIVER_MACSEC_SONIC
DRV_OBJS += ../src/drivers/driver_macsec_sonic.o
Expand Down
Loading
Loading