⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctrl_iface.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
字号:
/* * hostapd / UNIX domain socket -based control interface * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include "includes.h"#ifndef CONFIG_NATIVE_WINDOWS#include <sys/un.h>#include <sys/stat.h>#include <stddef.h>#include "hostapd.h"#include "eloop.h"#include "config.h"#include "ieee802_1x.h"#include "wpa.h"#include "radius/radius_client.h"#include "ieee802_11.h"#include "ctrl_iface.h"#include "sta_info.h"#include "accounting.h"#include "wps_hostapd.h"struct wpa_ctrl_dst {	struct wpa_ctrl_dst *next;	struct sockaddr_un addr;	socklen_t addrlen;	int debug_level;	int errors;};static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,				    const char *buf, size_t len);static int hostapd_ctrl_iface_attach(struct hostapd_data *hapd,				     struct sockaddr_un *from,				     socklen_t fromlen){	struct wpa_ctrl_dst *dst;	dst = os_zalloc(sizeof(*dst));	if (dst == NULL)		return -1;	os_memcpy(&dst->addr, from, sizeof(struct sockaddr_un));	dst->addrlen = fromlen;	dst->debug_level = MSG_INFO;	dst->next = hapd->ctrl_dst;	hapd->ctrl_dst = dst;	wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor attached",		    (u8 *) from->sun_path,		    fromlen - offsetof(struct sockaddr_un, sun_path));	return 0;}static int hostapd_ctrl_iface_detach(struct hostapd_data *hapd,				     struct sockaddr_un *from,				     socklen_t fromlen){	struct wpa_ctrl_dst *dst, *prev = NULL;	dst = hapd->ctrl_dst;	while (dst) {		if (fromlen == dst->addrlen &&		    os_memcmp(from->sun_path, dst->addr.sun_path,			      fromlen - offsetof(struct sockaddr_un, sun_path))		    == 0) {			if (prev == NULL)				hapd->ctrl_dst = dst->next;			else				prev->next = dst->next;			os_free(dst);			wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached",				    (u8 *) from->sun_path,				    fromlen -				    offsetof(struct sockaddr_un, sun_path));			return 0;		}		prev = dst;		dst = dst->next;	}	return -1;}static int hostapd_ctrl_iface_level(struct hostapd_data *hapd,				    struct sockaddr_un *from,				    socklen_t fromlen,				    char *level){	struct wpa_ctrl_dst *dst;	wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);	dst = hapd->ctrl_dst;	while (dst) {		if (fromlen == dst->addrlen &&		    os_memcmp(from->sun_path, dst->addr.sun_path,			      fromlen - offsetof(struct sockaddr_un, sun_path))		    == 0) {			wpa_hexdump(MSG_DEBUG, "CTRL_IFACE changed monitor "				    "level", (u8 *) from->sun_path, fromlen -				    offsetof(struct sockaddr_un, sun_path));			dst->debug_level = atoi(level);			return 0;		}		dst = dst->next;	}	return -1;}static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,				      struct sta_info *sta,				      char *buf, size_t buflen){	int len, res, ret;	if (sta == NULL) {		ret = os_snprintf(buf, buflen, "FAIL\n");		if (ret < 0 || (size_t) ret >= buflen)			return 0;		return ret;	}	len = 0;	ret = os_snprintf(buf + len, buflen - len, MACSTR "\n",			  MAC2STR(sta->addr));	if (ret < 0 || (size_t) ret >= buflen - len)		return len;	len += ret;	res = ieee802_11_get_mib_sta(hapd, sta, buf + len, buflen - len);	if (res >= 0)		len += res;	res = wpa_get_mib_sta(sta->wpa_sm, buf + len, buflen - len);	if (res >= 0)		len += res;	res = ieee802_1x_get_mib_sta(hapd, sta, buf + len, buflen - len);	if (res >= 0)		len += res;	return len;}static int hostapd_ctrl_iface_sta_first(struct hostapd_data *hapd,					char *buf, size_t buflen){	return hostapd_ctrl_iface_sta_mib(hapd, hapd->sta_list, buf, buflen);}static int hostapd_ctrl_iface_sta(struct hostapd_data *hapd,				  const char *txtaddr,				  char *buf, size_t buflen){	u8 addr[ETH_ALEN];	int ret;	if (hwaddr_aton(txtaddr, addr)) {		ret = os_snprintf(buf, buflen, "FAIL\n");		if (ret < 0 || (size_t) ret >= buflen)			return 0;		return ret;	}	return hostapd_ctrl_iface_sta_mib(hapd, ap_get_sta(hapd, addr),					  buf, buflen);}static int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd,				       const char *txtaddr,				       char *buf, size_t buflen){	u8 addr[ETH_ALEN];	struct sta_info *sta;	int ret;	if (hwaddr_aton(txtaddr, addr) ||	    (sta = ap_get_sta(hapd, addr)) == NULL) {		ret = os_snprintf(buf, buflen, "FAIL\n");		if (ret < 0 || (size_t) ret >= buflen)			return 0;		return ret;	}			return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen);}static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd,				      const char *txtaddr){	u8 addr[ETH_ALEN];	struct sta_info *sta;	wpa_printf(MSG_DEBUG, "CTRL_IFACE NEW_STA %s", txtaddr);	if (hwaddr_aton(txtaddr, addr))		return -1;	sta = ap_get_sta(hapd, addr);	if (sta)		return 0;	wpa_printf(MSG_DEBUG, "Add new STA " MACSTR " based on ctrl_iface "		   "notification", MAC2STR(addr));	sta = ap_sta_add(hapd, addr);	if (sta == NULL)		return -1;	hostapd_new_assoc_sta(hapd, sta, 0);	return 0;}#ifdef CONFIG_IEEE80211Wstatic int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,				       const char *txtaddr){	u8 addr[ETH_ALEN];	u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];	wpa_printf(MSG_DEBUG, "CTRL_IFACE SA_QUERY %s", txtaddr);	if (hwaddr_aton(txtaddr, addr))		return -1;	os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN);	ieee802_11_send_sa_query_req(hapd, addr, trans_id);	return 0;}#endif /* CONFIG_IEEE80211W */#ifdef CONFIG_WPSstatic int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt){	char *pin = os_strchr(txt, ' ');	if (pin == NULL)		return -1;	*pin++ = '\0';	return hostapd_wps_add_pin(hapd, txt, pin);}#endif /* CONFIG_WPS */static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,				       void *sock_ctx){	struct hostapd_data *hapd = eloop_ctx;	char buf[256];	int res;	struct sockaddr_un from;	socklen_t fromlen = sizeof(from);	char *reply;	const int reply_size = 4096;	int reply_len;	res = recvfrom(sock, buf, sizeof(buf) - 1, 0,		       (struct sockaddr *) &from, &fromlen);	if (res < 0) {		perror("recvfrom(ctrl_iface)");		return;	}	buf[res] = '\0';	wpa_hexdump_ascii(MSG_DEBUG, "RX ctrl_iface", (u8 *) buf, res);	reply = os_malloc(reply_size);	if (reply == NULL) {		sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,		       fromlen);		return;	}	os_memcpy(reply, "OK\n", 3);	reply_len = 3;	if (os_strcmp(buf, "PING") == 0) {		os_memcpy(reply, "PONG\n", 5);		reply_len = 5;	} else if (os_strcmp(buf, "MIB") == 0) {		reply_len = ieee802_11_get_mib(hapd, reply, reply_size);		if (reply_len >= 0) {			res = wpa_get_mib(hapd->wpa_auth, reply + reply_len,					  reply_size - reply_len);			if (res < 0)				reply_len = -1;			else				reply_len += res;		}		if (reply_len >= 0) {			res = ieee802_1x_get_mib(hapd, reply + reply_len,						 reply_size - reply_len);			if (res < 0)				reply_len = -1;			else				reply_len += res;		}		if (reply_len >= 0) {			res = radius_client_get_mib(hapd->radius,						    reply + reply_len,						    reply_size - reply_len);			if (res < 0)				reply_len = -1;			else				reply_len += res;		}	} else if (os_strcmp(buf, "STA-FIRST") == 0) {		reply_len = hostapd_ctrl_iface_sta_first(hapd, reply,							 reply_size);	} else if (os_strncmp(buf, "STA ", 4) == 0) {		reply_len = hostapd_ctrl_iface_sta(hapd, buf + 4, reply,						   reply_size);	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {		reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply,							reply_size);	} else if (os_strcmp(buf, "ATTACH") == 0) {		if (hostapd_ctrl_iface_attach(hapd, &from, fromlen))			reply_len = -1;	} else if (os_strcmp(buf, "DETACH") == 0) {		if (hostapd_ctrl_iface_detach(hapd, &from, fromlen))			reply_len = -1;	} else if (os_strncmp(buf, "LEVEL ", 6) == 0) {		if (hostapd_ctrl_iface_level(hapd, &from, fromlen,						    buf + 6))			reply_len = -1;	} else if (os_strncmp(buf, "NEW_STA ", 8) == 0) {		if (hostapd_ctrl_iface_new_sta(hapd, buf + 8))			reply_len = -1;#ifdef CONFIG_IEEE80211W	} else if (os_strncmp(buf, "SA_QUERY ", 9) == 0) {		if (hostapd_ctrl_iface_sa_query(hapd, buf + 9))			reply_len = -1;#endif /* CONFIG_IEEE80211W */#ifdef CONFIG_WPS	} else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {		if (hostapd_ctrl_iface_wps_pin(hapd, buf + 8))			reply_len = -1;	} else if (os_strcmp(buf, "WPS_PBC") == 0) {		if (hostapd_wps_button_pushed(hapd))			reply_len = -1;#endif /* CONFIG_WPS */	} else {		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);		reply_len = 16;	}	if (reply_len < 0) {		os_memcpy(reply, "FAIL\n", 5);		reply_len = 5;	}	sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, fromlen);	os_free(reply);}static char * hostapd_ctrl_iface_path(struct hostapd_data *hapd){	char *buf;	size_t len;	if (hapd->conf->ctrl_interface == NULL)		return NULL;	len = os_strlen(hapd->conf->ctrl_interface) +		os_strlen(hapd->conf->iface) + 2;	buf = os_malloc(len);	if (buf == NULL)		return NULL;	os_snprintf(buf, len, "%s/%s",		    hapd->conf->ctrl_interface, hapd->conf->iface);	buf[len - 1] = '\0';	return buf;}static void hostapd_ctrl_iface_msg_cb(void *ctx, int level,				      const char *txt, size_t len){	struct hostapd_data *hapd = ctx;	if (hapd == NULL)		return;	hostapd_ctrl_iface_send(hapd, level, txt, len);}int hostapd_ctrl_iface_init(struct hostapd_data *hapd){	struct sockaddr_un addr;	int s = -1;	char *fname = NULL;	hapd->ctrl_sock = -1;	if (hapd->conf->ctrl_interface == NULL)		return 0;	if (mkdir(hapd->conf->ctrl_interface, S_IRWXU | S_IRWXG) < 0) {		if (errno == EEXIST) {			wpa_printf(MSG_DEBUG, "Using existing control "				   "interface directory.");		} else {			perror("mkdir[ctrl_interface]");			goto fail;		}	}	if (hapd->conf->ctrl_interface_gid_set &&	    chown(hapd->conf->ctrl_interface, 0,		  hapd->conf->ctrl_interface_gid) < 0) {		perror("chown[ctrl_interface]");		return -1;	}	if (os_strlen(hapd->conf->ctrl_interface) + 1 +	    os_strlen(hapd->conf->iface) >= sizeof(addr.sun_path))		goto fail;	s = socket(PF_UNIX, SOCK_DGRAM, 0);	if (s < 0) {		perror("socket(PF_UNIX)");		goto fail;	}	os_memset(&addr, 0, sizeof(addr));#ifdef __FreeBSD__	addr.sun_len = sizeof(addr);#endif /* __FreeBSD__ */	addr.sun_family = AF_UNIX;	fname = hostapd_ctrl_iface_path(hapd);	if (fname == NULL)		goto fail;	os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {		perror("bind(PF_UNIX)");		goto fail;	}	if (hapd->conf->ctrl_interface_gid_set &&	    chown(fname, 0, hapd->conf->ctrl_interface_gid) < 0) {		perror("chown[ctrl_interface/ifname]");		goto fail;	}	if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {		perror("chmod[ctrl_interface/ifname]");		goto fail;	}	os_free(fname);	hapd->ctrl_sock = s;	eloop_register_read_sock(s, hostapd_ctrl_iface_receive, hapd,				 NULL);	wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb);	return 0;fail:	if (s >= 0)		close(s);	if (fname) {		unlink(fname);		os_free(fname);	}	return -1;}void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd){	struct wpa_ctrl_dst *dst, *prev;	if (hapd->ctrl_sock > -1) {		char *fname;		eloop_unregister_read_sock(hapd->ctrl_sock);		close(hapd->ctrl_sock);		hapd->ctrl_sock = -1;		fname = hostapd_ctrl_iface_path(hapd);		if (fname)			unlink(fname);		os_free(fname);		if (hapd->conf->ctrl_interface &&		    rmdir(hapd->conf->ctrl_interface) < 0) {			if (errno == ENOTEMPTY) {				wpa_printf(MSG_DEBUG, "Control interface "					   "directory not empty - leaving it "					   "behind");			} else {				perror("rmdir[ctrl_interface]");			}		}	}	dst = hapd->ctrl_dst;	while (dst) {		prev = dst;		dst = dst->next;		os_free(prev);	}}static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,				    const char *buf, size_t len){	struct wpa_ctrl_dst *dst, *next;	struct msghdr msg;	int idx;	struct iovec io[2];	char levelstr[10];	dst = hapd->ctrl_dst;	if (hapd->ctrl_sock < 0 || dst == NULL)		return;	os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);	io[0].iov_base = levelstr;	io[0].iov_len = os_strlen(levelstr);	io[1].iov_base = (char *) buf;	io[1].iov_len = len;	os_memset(&msg, 0, sizeof(msg));	msg.msg_iov = io;	msg.msg_iovlen = 2;	idx = 0;	while (dst) {		next = dst->next;		if (level >= dst->debug_level) {			wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send",				    (u8 *) dst->addr.sun_path, dst->addrlen -				    offsetof(struct sockaddr_un, sun_path));			msg.msg_name = &dst->addr;			msg.msg_namelen = dst->addrlen;			if (sendmsg(hapd->ctrl_sock, &msg, 0) < 0) {				int _errno = errno;				wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: "					   "%d - %s",					   idx, errno, strerror(errno));				dst->errors++;				if (dst->errors > 10 || _errno == ENOENT) {					hostapd_ctrl_iface_detach(						hapd, &dst->addr,						dst->addrlen);				}			} else				dst->errors = 0;		}		idx++;		dst = next;	}}#endif /* CONFIG_NATIVE_WINDOWS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -