Skip to content

Commit

Permalink
Changes in Hostapd to Support PAC
Browse files Browse the repository at this point in the history
  • Loading branch information
vijaya-ops committed Apr 8, 2024
1 parent 3c7fd8e commit ba5931c
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 11 deletions.
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
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
102 changes: 93 additions & 9 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,28 @@
#pragma pack(push, 1)
#endif /* _MSC_VER */

#if 0
struct ieee8023_hdr {
u8 dest[6];
u8 src[6];
u16 ethertype;
} STRUCT_PACKED;
#endif

#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 +98,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 +115,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 +193,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 +224,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 +233,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 +250,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 +308,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 +355,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 +402,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 +417,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 +438,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 +474,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 +483,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

0 comments on commit ba5931c

Please sign in to comment.