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

📄 driver_bsd.c

📁 一个Linux下无线网卡的设置工具
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct ieee80211req_mlme mlme;	int ret = 0;	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);	/*	 * NB: Don't need to set the freq or cipher-related state as	 *     this is implied by the bssid which is used to locate	 *     the scanned node state which holds it.  The ssid is	 *     needed to disambiguate an AP that broadcasts multiple	 *     ssid's but uses the same bssid.	 */	/* XXX error handling is wrong but unclear what to do... */	if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)		ret = -1;	if (wpa_driver_bsd_set_ssid(drv, params->ssid, params->ssid_len) < 0)		ret = -1;	memset(&mlme, 0, sizeof(mlme));	mlme.im_op = IEEE80211_MLME_ASSOC;	memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);	if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0)		ret = -1;	return ret;}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){	char buf[2048];	struct if_announcemsghdr *ifan;	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;	}	ifan = (struct if_announcemsghdr *) rtm;	switch (rtm->rtm_type) {	case RTM_IFANNOUNCE:		memset(&event, 0, sizeof(event));		/* XXX name buffer must be >= IFNAMSIZ */		/* XXX check return value */		if_indextoname(ifan->ifan_index, event.interface_status.ifname);		switch (ifan->ifan_what) {		case IFAN_ARRIVAL:			event.interface_status.ievent = EVENT_INTERFACE_ADDED;			break;		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:		switch (ifan->ifan_what) {		case RTM_IEEE80211_ASSOC:			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_REASSOC:		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));			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;	}}/* 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;	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;		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);		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);					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);					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){	struct wpa_driver_bsd_data *drv;	drv = malloc(sizeof(*drv));	if (drv == NULL)		return NULL;	memset(drv, 0, sizeof(*drv));	drv->sock = socket(PF_INET, SOCK_DGRAM, 0);	if (drv->sock < 0) {		free(drv);		return NULL;	}	drv->route = socket(PF_ROUTE, SOCK_RAW, 0);	if (drv->route < 0) {		close(drv->sock);		free(drv);		return NULL;	}	eloop_register_read_sock(drv->route,		wpa_driver_bsd_event_receive, ctx, NULL);	drv->ctx = ctx;	strncpy(drv->ifname, ifname, sizeof(drv->ifname));	return drv;}static voidwpa_driver_bsd_deinit(void *priv){	struct wpa_driver_bsd_data *drv = priv;	int flags;	/* NB: mark interface down */	if (getifflags(drv, &flags) == 0)		(void) setifflags(drv, flags &~ IFF_UP);	(void) close(drv->route);		/* ioctl socket */	(void) close(drv->sock);		/* event socket */	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,};

⌨️ 快捷键说明

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