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

📄 driver_bsd.c

📁 WLAN无线网络管理的最新程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		return -1;	if (params->wpa_ie_len &&	    set80211param(drv, IEEE80211_IOC_WPA,			  params->wpa_ie[0] == RSN_INFO_ELEM ? 2 : 1) < 0)		return -1;	os_memset(&mlme, 0, sizeof(mlme));	mlme.im_op = IEEE80211_MLME_ASSOC;#ifdef NEW_FREEBSD_MLME_ASSOC	if (params->ssid != NULL)		os_memcpy(mlme.im_ssid, params->ssid, params->ssid_len);	mlme.im_ssid_len = params->ssid_len;#endif	if (params->bssid != NULL)		os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);	if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0)		return -1;	return 0;}static intwpa_driver_bsd_set_auth_alg(void *priv, int auth_alg){	struct wpa_driver_bsd_data *drv = priv;	int authmode;	if ((auth_alg & AUTH_ALG_OPEN_SYSTEM) &&	    (auth_alg & AUTH_ALG_SHARED_KEY))		authmode = IEEE80211_AUTH_AUTO;	else if (auth_alg & AUTH_ALG_SHARED_KEY)		authmode = IEEE80211_AUTH_SHARED;	else		authmode = IEEE80211_AUTH_OPEN;	return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode);}static intwpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len){	struct wpa_driver_bsd_data *drv = priv;	int flags;	/* NB: interface must be marked UP to do a scan */	if (getifflags(drv, &flags) != 0 || setifflags(drv, flags | IFF_UP) != 0)		return -1;	/* set desired ssid before scan */	if (wpa_driver_bsd_set_ssid(drv, ssid, ssid_len) < 0)		return -1;	/* NB: net80211 delivers a scan complete event so no need to poll */	return set80211param(drv, IEEE80211_IOC_SCAN_REQ, 0);}#include <net/route.h>#include <net80211/ieee80211_freebsd.h>static voidwpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx){	struct wpa_driver_bsd_data *drv = sock_ctx;	char buf[2048];	struct if_announcemsghdr *ifan;	struct if_msghdr *ifm;	struct rt_msghdr *rtm;	union wpa_event_data event;	struct ieee80211_michael_event *mic;	int n;	n = read(sock, buf, sizeof(buf));	if (n < 0) {		if (errno != EINTR && errno != EAGAIN)			perror("read(PF_ROUTE)");		return;	}	rtm = (struct rt_msghdr *) buf;	if (rtm->rtm_version != RTM_VERSION) {		wpa_printf(MSG_DEBUG, "Routing message version %d not "			"understood\n", rtm->rtm_version);		return;	}	os_memset(&event, 0, sizeof(event));	switch (rtm->rtm_type) {	case RTM_IFANNOUNCE:		ifan = (struct if_announcemsghdr *) rtm;		if (ifan->ifan_index != drv->ifindex)			break;		strlcpy(event.interface_status.ifname, drv->ifname,			sizeof(event.interface_status.ifname));		switch (ifan->ifan_what) {		case IFAN_DEPARTURE:			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;		default:			return;		}		wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s",			   event.interface_status.ifname,			   ifan->ifan_what == IFAN_DEPARTURE ?				"removed" : "added");		wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);		break;	case RTM_IEEE80211:		ifan = (struct if_announcemsghdr *) rtm;		if (ifan->ifan_index != drv->ifindex)			break;		switch (ifan->ifan_what) {		case RTM_IEEE80211_ASSOC:		case RTM_IEEE80211_REASSOC:			wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);			break;		case RTM_IEEE80211_DISASSOC:			wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL);			break;		case RTM_IEEE80211_SCAN:			wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);			break;		case RTM_IEEE80211_REPLAY:			/* ignore */			break;		case RTM_IEEE80211_MICHAEL:			mic = (struct ieee80211_michael_event *) &ifan[1];			wpa_printf(MSG_DEBUG,				"Michael MIC failure wireless event: "				"keyix=%u src_addr=" MACSTR, mic->iev_keyix,				MAC2STR(mic->iev_src));			os_memset(&event, 0, sizeof(event));			event.michael_mic_failure.unicast =				!IEEE80211_IS_MULTICAST(mic->iev_dst);			wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE,				&event);			break;		}		break;	case RTM_IFINFO:		ifm = (struct if_msghdr *) rtm;		if (ifm->ifm_index != drv->ifindex)			break;		if ((rtm->rtm_flags & RTF_UP) == 0) {			strlcpy(event.interface_status.ifname, drv->ifname,				sizeof(event.interface_status.ifname));			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",				   event.interface_status.ifname);			wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);		}		break;	}}/* Compare function for sorting scan results. Return >0 if @b is consider * better. */static intwpa_scan_result_compar(const void *a, const void *b){	const struct wpa_scan_result *wa = a;	const struct wpa_scan_result *wb = b;	/* WPA/WPA2 support preferred */	if ((wb->wpa_ie_len || wb->rsn_ie_len) &&	    !(wa->wpa_ie_len || wa->rsn_ie_len))		return 1;	if (!(wb->wpa_ie_len || wb->rsn_ie_len) &&	    (wa->wpa_ie_len || wa->rsn_ie_len))		return -1;	/* privacy support preferred */	if ((wa->caps & IEEE80211_CAPINFO_PRIVACY) &&	    (wb->caps & IEEE80211_CAPINFO_PRIVACY) == 0)		return 1;	if ((wa->caps & IEEE80211_CAPINFO_PRIVACY) == 0 &&	    (wb->caps & IEEE80211_CAPINFO_PRIVACY))		return -1;	/* best/max rate preferred if signal level close enough XXX */	if (wa->maxrate != wb->maxrate && abs(wb->level - wa->level) < 5)		return wb->maxrate - wa->maxrate;	/* use freq for channel preference */	/* all things being equal, use signal level */	return wb->level - wa->level;}static intgetmaxrate(uint8_t rates[15], uint8_t nrates){	int i, maxrate = -1;	for (i = 0; i < nrates; i++) {		int rate = rates[i] & IEEE80211_RATE_VAL;		if (rate > maxrate)			rate = maxrate;	}	return maxrate;}/* unalligned little endian access */     #define LE_READ_4(p)					\	((u_int32_t)					\	 ((((const u_int8_t *)(p))[0]      ) |		\	  (((const u_int8_t *)(p))[1] <<  8) |		\	  (((const u_int8_t *)(p))[2] << 16) |		\	  (((const u_int8_t *)(p))[3] << 24)))static int __inlineiswpaoui(const u_int8_t *frm){	return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);}static intwpa_driver_bsd_get_scan_results(void *priv,				     struct wpa_scan_result *results,				     size_t max_size){#define	min(a,b)	((a)>(b)?(b):(a))	struct wpa_driver_bsd_data *drv = priv;	uint8_t buf[24*1024];	uint8_t *cp, *vp;	struct ieee80211req_scan_result *sr;	struct wpa_scan_result *wsr;	int len, ielen;	os_memset(results, 0, max_size * sizeof(struct wpa_scan_result));	len = get80211var(drv, IEEE80211_IOC_SCAN_RESULTS, buf, sizeof(buf));	if (len < 0)		return -1;	cp = buf;	wsr = results;	while (len >= sizeof(struct ieee80211req_scan_result)) {		sr = (struct ieee80211req_scan_result *) cp;		os_memcpy(wsr->bssid, sr->isr_bssid, IEEE80211_ADDR_LEN);		wsr->ssid_len = sr->isr_ssid_len;		wsr->freq = sr->isr_freq;		wsr->noise = sr->isr_noise;		wsr->qual = sr->isr_rssi;		wsr->level = 0;		/* XXX? */		wsr->caps = sr->isr_capinfo;		wsr->maxrate = getmaxrate(sr->isr_rates, sr->isr_nrates);		vp = (u_int8_t *)(sr+1);		os_memcpy(wsr->ssid, vp, sr->isr_ssid_len);		if (sr->isr_ie_len > 0) {			vp += sr->isr_ssid_len;			ielen = sr->isr_ie_len;			while (ielen > 0) {				switch (vp[0]) {				case IEEE80211_ELEMID_VENDOR:					if (!iswpaoui(vp))						break;					wsr->wpa_ie_len =					    min(2+vp[1], SSID_MAX_WPA_IE_LEN);					os_memcpy(wsr->wpa_ie, vp,						  wsr->wpa_ie_len);					break;				case IEEE80211_ELEMID_RSN:					wsr->rsn_ie_len =					    min(2+vp[1], SSID_MAX_WPA_IE_LEN);					os_memcpy(wsr->rsn_ie, vp,						  wsr->rsn_ie_len);					break;				}				ielen -= 2+vp[1];				vp += 2+vp[1];			}		}		cp += sr->isr_len, len -= sr->isr_len;		wsr++;	}	qsort(results, wsr - results, sizeof(struct wpa_scan_result),	      wpa_scan_result_compar);	wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%d BSSes)",		   len, wsr - results);	return wsr - results;#undef min}static void *wpa_driver_bsd_init(void *ctx, const char *ifname){#define	GETPARAM(drv, param, v) \	(((v) = get80211param(drv, param)) != -1)	struct wpa_driver_bsd_data *drv;	drv = os_zalloc(sizeof(*drv));	if (drv == NULL)		return NULL;	/*	 * NB: We require the interface name be mappable to an index.	 *     This implies we do not support having wpa_supplicant	 *     wait for an interface to appear.  This seems ok; that	 *     doesn't belong here; it's really the job of devd.	 */	drv->ifindex = if_nametoindex(ifname);	if (drv->ifindex == 0) {		wpa_printf(MSG_DEBUG, "%s: interface %s does not exist",			   __func__, ifname);		goto fail1;	}	drv->sock = socket(PF_INET, SOCK_DGRAM, 0);	if (drv->sock < 0)		goto fail1;	drv->route = socket(PF_ROUTE, SOCK_RAW, 0);	if (drv->route < 0)		goto fail;	eloop_register_read_sock(drv->route,		wpa_driver_bsd_event_receive, ctx, drv);	drv->ctx = ctx;	os_strncpy(drv->ifname, ifname, sizeof(drv->ifname));	if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) {		wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s",			__func__, strerror(errno));		goto fail;	}	if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) {		wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s",			__func__, strerror(errno));		goto fail;	}	if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) {		wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s",			__func__, strerror(errno));		goto fail;	}	if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_MANUAL) < 0) {		wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based "			   "roaming: %s", __func__, strerror(errno));		goto fail;	}	if (set80211param(drv, IEEE80211_IOC_WPA, 1+2) < 0) {		wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support %s",			   __func__, strerror(errno));		goto fail;	}	return drv;fail:	close(drv->sock);fail1:	os_free(drv);	return NULL;#undef GETPARAM}static voidwpa_driver_bsd_deinit(void *priv){	struct wpa_driver_bsd_data *drv = priv;	int flags;	eloop_unregister_read_sock(drv->route);	/* NB: mark interface down */	if (getifflags(drv, &flags) == 0)		(void) setifflags(drv, flags &~ IFF_UP);	wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy);	if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0)		wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state",			__func__);	(void) close(drv->route);		/* ioctl socket */	(void) close(drv->sock);		/* event socket */	os_free(drv);}const struct wpa_driver_ops wpa_driver_bsd_ops = {	.name			= "bsd",	.desc			= "BSD 802.11 support (Atheros, etc.)",	.init			= wpa_driver_bsd_init,	.deinit			= wpa_driver_bsd_deinit,	.get_bssid		= wpa_driver_bsd_get_bssid,	.get_ssid		= wpa_driver_bsd_get_ssid,	.set_wpa		= wpa_driver_bsd_set_wpa,	.set_key		= wpa_driver_bsd_set_key,	.set_countermeasures	= wpa_driver_bsd_set_countermeasures,	.set_drop_unencrypted	= wpa_driver_bsd_set_drop_unencrypted,	.scan			= wpa_driver_bsd_scan,	.get_scan_results	= wpa_driver_bsd_get_scan_results,	.deauthenticate		= wpa_driver_bsd_deauthenticate,	.disassociate		= wpa_driver_bsd_disassociate,	.associate		= wpa_driver_bsd_associate,	.set_auth_alg		= wpa_driver_bsd_set_auth_alg,};

⌨️ 快捷键说明

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