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
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
@@ -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
@@ -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 */
@@ -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 */
}
}
@@ -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;

@@ -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);
@@ -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)
{
@@ -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;
}
6 changes: 6 additions & 0 deletions src/ap/sta_info.h
Original file line number Diff line number Diff line change
@@ -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)
@@ -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
};


12 changes: 12 additions & 0 deletions src/drivers/driver.h
Original file line number Diff line number Diff line change
@@ -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
};

/**
106 changes: 91 additions & 15 deletions src/drivers/driver_wired.c
Original file line number Diff line number Diff line change
@@ -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
@@ -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;
};

@@ -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 */
@@ -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;
@@ -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;
@@ -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__ */


@@ -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) {
@@ -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) {
@@ -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",
@@ -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;
@@ -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)
{
@@ -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;
@@ -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);
}

@@ -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",
@@ -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
@@ -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
42 changes: 42 additions & 0 deletions src/utils/json.c
Original file line number Diff line number Diff line change
@@ -688,3 +688,45 @@ void json_value_sep(struct wpabuf *json)
{
wpabuf_put_u8(json, ',');
}

#ifdef CONFIG_SONIC_HOSTAPD
int json_get_array_size(struct json_token *array)
{
struct json_token *child = NULL;
int size = 0;

if (array == NULL)
{
return 0;
}

child = array->child;

while(child != NULL)
{
size++;
child = child->sibling;
}

return (int)size;
}

struct json_token* json_get_array_item(struct json_token *array, int index)
{
struct json_token *current_child = NULL;

if ((array == NULL) || (index < 0))
{
return NULL;
}

current_child = array->child;
while ((current_child != NULL) && (index > 0))
{
index--;
current_child = current_child->sibling;
}

return current_child;
}
#endif
5 changes: 4 additions & 1 deletion src/utils/json.h
Original file line number Diff line number Diff line change
@@ -53,5 +53,8 @@ void json_end_object(struct wpabuf *json);
void json_start_array(struct wpabuf *json, const char *name);
void json_end_array(struct wpabuf *json);
void json_value_sep(struct wpabuf *json);

#ifdef CONFIG_SONIC_HOSTAPD
int json_get_array_size(struct json_token *array);
struct json_token* json_get_array_item(struct json_token *array, int index);
#endif
#endif /* JSON_H */