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

📄 ctrl_iface.c

📁 一个Linux下无线网卡的设置工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * WPA Supplicant / UNIX domain and UDP socket -based control interface * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.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 <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#ifndef CONFIG_NATIVE_WINDOWS#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/un.h>#include <sys/uio.h>#endif /* CONFIG_NATIVE_WINDOWS */#include "common.h"#include "eloop.h"#include "wpa.h"#include "wpa_supplicant.h"#include "config.h"#include "eapol_sm.h"#include "wpa_supplicant_i.h"#include "ctrl_iface.h"#include "l2_packet.h"#include "preauth.h"#include "wpa_ctrl.h"#include "eap.h"#ifdef CONFIG_CTRL_IFACE_UDP#define CTRL_IFACE_SOCK struct sockaddr_in#else /* CONFIG_CTRL_IFACE_UDP */#define CTRL_IFACE_SOCK struct sockaddr_un#endif /* CONFIG_CTRL_IFACE_UDP *//** * struct wpa_ctrl_dst - Internal data structure of control interface monitors * * This structure is used to store information about registered control * interface monitors into struct wpa_supplicant. This data is private to * ctrl_iface.c and should not be touched directly from other files. */struct wpa_ctrl_dst {	struct wpa_ctrl_dst *next;	CTRL_IFACE_SOCK addr;	socklen_t addrlen;	int debug_level;	int errors;};static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,					 char *cmd){	char *value;	int ret = 0;	value = strchr(cmd, ' ');	if (value == NULL)		return -1;	*value++ = '\0';	wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value);	if (strcasecmp(cmd, "EAPOL::heldPeriod") == 0) {		eapol_sm_configure(wpa_s->eapol,				   atoi(value), -1, -1, -1);	} else if (strcasecmp(cmd, "EAPOL::authPeriod") == 0) {		eapol_sm_configure(wpa_s->eapol,				   -1, atoi(value), -1, -1);	} else if (strcasecmp(cmd, "EAPOL::startPeriod") == 0) {		eapol_sm_configure(wpa_s->eapol,				   -1, -1, atoi(value), -1);	} else if (strcasecmp(cmd, "EAPOL::maxStart") == 0) {		eapol_sm_configure(wpa_s->eapol,				   -1, -1, -1, atoi(value));	} else if (strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {		if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,				     atoi(value)))			ret = -1;	} else if (strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") == 0) {		if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,				     atoi(value)))			ret = -1;	} else if (strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {		if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))			ret = -1;	} else		ret = -1;	return ret;}static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,					     char *addr){	u8 bssid[ETH_ALEN];	if (hwaddr_aton(addr, bssid)) {		wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "			   "'%s'", addr);		return -1;	}	wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));	rsn_preauth_deinit(wpa_s->wpa);	if (rsn_preauth_init(wpa_s->wpa, bssid, wpa_s->current_ssid))		return -1;	return 0;}static int wpa_supplicant_ctrl_iface_attach(struct wpa_supplicant *wpa_s,					    CTRL_IFACE_SOCK *from,					    socklen_t fromlen){	struct wpa_ctrl_dst *dst;	dst = malloc(sizeof(*dst));	if (dst == NULL)		return -1;	memset(dst, 0, sizeof(*dst));	memcpy(&dst->addr, from, sizeof(CTRL_IFACE_SOCK));	dst->addrlen = fromlen;	dst->debug_level = MSG_INFO;	dst->next = wpa_s->ctrl_dst;	wpa_s->ctrl_dst = dst;#ifdef CONFIG_CTRL_IFACE_UDP	wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor attached %s:%d",		   inet_ntoa(from->sin_addr), ntohs(from->sin_port));#else /* CONFIG_CTRL_IFACE_UDP */	wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor attached",		    (u8 *) from->sun_path, fromlen - sizeof(from->sun_family));#endif /* CONFIG_CTRL_IFACE_UDP */	return 0;}static int wpa_supplicant_ctrl_iface_detach(struct wpa_supplicant *wpa_s,					    CTRL_IFACE_SOCK *from,					    socklen_t fromlen){	struct wpa_ctrl_dst *dst, *prev = NULL;	dst = wpa_s->ctrl_dst;	while (dst) {#ifdef CONFIG_CTRL_IFACE_UDP		if (from->sin_addr.s_addr == dst->addr.sin_addr.s_addr &&		    from->sin_port == dst->addr.sin_port) {			if (prev == NULL)				wpa_s->ctrl_dst = dst->next;			else				prev->next = dst->next;			free(dst);			wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor detached "				   "%s:%d", inet_ntoa(from->sin_addr),				   ntohs(from->sin_port));			return 0;		}#else /* CONFIG_CTRL_IFACE_UDP */		if (fromlen == dst->addrlen &&		    memcmp(from->sun_path, dst->addr.sun_path,			   fromlen - sizeof(from->sun_family)) == 0) {			if (prev == NULL)				wpa_s->ctrl_dst = dst->next;			else				prev->next = dst->next;			free(dst);			wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached",				    (u8 *) from->sun_path,				    fromlen - sizeof(from->sun_family));			return 0;		}#endif /* CONFIG_CTRL_IFACE_UDP */		prev = dst;		dst = dst->next;	}	return -1;}static int wpa_supplicant_ctrl_iface_level(struct wpa_supplicant *wpa_s,					   CTRL_IFACE_SOCK *from,					   socklen_t fromlen,					   char *level){	struct wpa_ctrl_dst *dst;	wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);	dst = wpa_s->ctrl_dst;	while (dst) {#ifdef CONFIG_CTRL_IFACE_UDP		if (from->sin_addr.s_addr == dst->addr.sin_addr.s_addr &&		    from->sin_port == dst->addr.sin_port) {			wpa_printf(MSG_DEBUG, "CTRL_IFACE changed monitor "				   "level %s:%d", inet_ntoa(from->sin_addr),				   ntohs(from->sin_port));			dst->debug_level = atoi(level);			return 0;		}#else /* CONFIG_CTRL_IFACE_UDP */		if (fromlen == dst->addrlen &&		    memcmp(from->sun_path, dst->addr.sun_path,			   fromlen - sizeof(from->sun_family)) == 0) {			wpa_hexdump(MSG_DEBUG, "CTRL_IFACE changed monitor "				    "level", (u8 *) from->sun_path,				    fromlen - sizeof(from->sun_family));			dst->debug_level = atoi(level);			return 0;		}#endif /* CONFIG_CTRL_IFACE_UDP */		dst = dst->next;	}	return -1;}static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,					      char *rsp){	char *pos, *id_pos;	int id;	struct wpa_ssid *ssid;	pos = strchr(rsp, '-');	if (pos == NULL)		return -1;	*pos++ = '\0';	id_pos = pos;	pos = strchr(pos, ':');	if (pos == NULL)		return -1;	*pos++ = '\0';	id = atoi(id_pos);	wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);	wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",			      (u8 *) pos, strlen(pos));	ssid = wpa_config_get_network(wpa_s->conf, id);	if (ssid == NULL) {		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "			   "to update", id);		return -1;	}	if (strcmp(rsp, "IDENTITY") == 0) {		free(ssid->identity);		ssid->identity = (u8 *) strdup(pos);		ssid->identity_len = strlen(pos);		ssid->pending_req_identity = 0;		if (ssid == wpa_s->current_ssid)			wpa_s->reassociate = 1;	} else if (strcmp(rsp, "PASSWORD") == 0) {		free(ssid->password);		ssid->password = (u8 *) strdup(pos);		ssid->password_len = strlen(pos);		ssid->pending_req_password = 0;		if (ssid == wpa_s->current_ssid)			wpa_s->reassociate = 1;	} else if (strcmp(rsp, "NEW_PASSWORD") == 0) {		free(ssid->new_password);		ssid->new_password = (u8 *) strdup(pos);		ssid->new_password_len = strlen(pos);		ssid->pending_req_new_password = 0;		if (ssid == wpa_s->current_ssid)			wpa_s->reassociate = 1;	} else if (strcmp(rsp, "PIN") == 0) {		free(ssid->pin);		ssid->pin = strdup(pos);		ssid->pending_req_pin = 0;		if (ssid == wpa_s->current_ssid)			wpa_s->reassociate = 1;	} else if (strcmp(rsp, "OTP") == 0) {		free(ssid->otp);		ssid->otp = (u8 *) strdup(pos);		ssid->otp_len = strlen(pos);		free(ssid->pending_req_otp);		ssid->pending_req_otp = NULL;		ssid->pending_req_otp_len = 0;	} else if (strcmp(rsp, "PASSPHRASE") == 0) {		free(ssid->private_key_passwd);		ssid->private_key_passwd = (u8 *) strdup(pos);		ssid->pending_req_passphrase = 0;		if (ssid == wpa_s->current_ssid)			wpa_s->reassociate = 1;	} else {		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", rsp);		return -1;	}	return 0;}static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,					    const char *params,					    char *buf, size_t buflen){	char *pos, *end, tmp[30];	int res, verbose;	verbose = strcmp(params, "-VERBOSE") == 0;	pos = buf;	end = buf + buflen;	if (wpa_s->wpa_state >= WPA_ASSOCIATED) {		pos += snprintf(pos, end - pos, "bssid=" MACSTR "\n",				MAC2STR(wpa_s->bssid));		if (wpa_s->current_ssid) {			pos += snprintf(pos, end - pos, "ssid=%s\n",					wpa_ssid_txt(wpa_s->current_ssid->ssid,						     wpa_s->current_ssid->						     ssid_len));		}		pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);	}	pos += snprintf(pos, end - pos, "wpa_state=%s\n",			wpa_supplicant_state_txt(wpa_s->wpa_state));	if (wpa_s->l2 &&	    l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0)		pos += snprintf(pos, end - pos, "ip_address=%s\n", tmp);	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||	    wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {		res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,					  verbose);		if (res >= 0)			pos += res;	}	res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);	if (res >= 0)		pos += res;	return pos - buf;}static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,					   char *cmd){	char *pos;	int id;	struct wpa_ssid *ssid;	u8 bssid[ETH_ALEN];	/* cmd: "<network id> <BSSID>" */	pos = strchr(cmd, ' ');	if (pos == NULL)		return -1;	*pos++ = '\0';	id = atoi(cmd);	wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);	if (hwaddr_aton(pos, bssid)) {		wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);		return -1;	}	ssid = wpa_config_get_network(wpa_s->conf, id);	if (ssid == NULL) {		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "			   "to update", id);		return -1;	}	memcpy(ssid->bssid, bssid, ETH_ALEN);	ssid->bssid_set =		memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0;			return 0;}static int wpa_supplicant_ctrl_iface_list_networks(	struct wpa_supplicant *wpa_s, char *buf, size_t buflen){	char *pos, *end;	struct wpa_ssid *ssid;	pos = buf;	end = buf + buflen;	pos += snprintf(pos, end - pos, "network id / ssid / bssid / flags\n");	ssid = wpa_s->conf->ssid;	while (ssid) {		pos += snprintf(pos, end - pos, "%d\t%s",				ssid->id,				wpa_ssid_txt(ssid->ssid, ssid->ssid_len));		if (ssid->bssid_set) {			pos += snprintf(pos, end - pos, "\t" MACSTR,					MAC2STR(ssid->bssid));		} else {			pos += snprintf(pos, end - pos, "\tany");		}		pos += snprintf(pos, end - pos, "\t%s%s",				ssid == wpa_s->current_ssid ? "[CURRENT]" : "",				ssid->disabled ? "[DISABLED]" : "");		pos += snprintf(pos, end - pos, "\n");		ssid = ssid->next;	}	return pos - buf;}static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher){	int first = 1;	pos += snprintf(pos, end - pos, "-");	if (cipher & WPA_CIPHER_NONE) {		pos += snprintf(pos, end - pos, "%sNONE", first ? "" : "+");		first = 0;	}	if (cipher & WPA_CIPHER_WEP40) {		pos += snprintf(pos, end - pos, "%sWEP40", first ? "" : "+");		first = 0;	}	if (cipher & WPA_CIPHER_WEP104) {		pos += snprintf(pos, end - pos, "%sWEP104", first ? "" : "+");		first = 0;	}	if (cipher & WPA_CIPHER_TKIP) {		pos += snprintf(pos, end - pos, "%sTKIP", first ? "" : "+");		first = 0;	}	if (cipher & WPA_CIPHER_CCMP) {		pos += snprintf(pos, end - pos, "%sCCMP", first ? "" : "+");		first = 0;	}	return pos;}static char * wpa_supplicant_ie_txt(struct wpa_supplicant *wpa_s,				    char *pos, char *end, const char *proto,				    const u8 *ie, size_t ie_len){	struct wpa_ie_data data;	int first;	pos += snprintf(pos, end - pos, "[%s-", proto);	if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {		pos += snprintf(pos, end - pos, "?]");		return pos;	}	first = 1;	if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {		pos += snprintf(pos, end - pos, "%sEAP", first ? "" : "+");		first = 0;	}	if (data.key_mgmt & WPA_KEY_MGMT_PSK) {		pos += snprintf(pos, end - pos, "%sPSK", first ? "" : "+");		first = 0;	}	if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {		pos += snprintf(pos, end - pos, "%sNone", first ? "" : "+");		first = 0;	}	pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);	if (data.capabilities & WPA_CAPABILITY_PREAUTH)		pos += snprintf(pos, end - pos, "-preauth");	pos += snprintf(pos, end - pos, "]");	return pos;}static int wpa_supplicant_ctrl_iface_scan_results(	struct wpa_supplicant *wpa_s, char *buf, size_t buflen){	char *pos, *end;	struct wpa_scan_result *res;	int i;	if (wpa_s->scan_results == NULL &&	    wpa_supplicant_get_scan_results(wpa_s) < 0)		return 0;	pos = buf;	end = buf + buflen;	pos += snprintf(pos, end - pos, "bssid / frequency / signal level / "			"flags / ssid\n");	for (i = 0; i < wpa_s->num_scan_results; i++) {		res = &wpa_s->scan_results[i];		pos += snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",				MAC2STR(res->bssid), res->freq, res->level);		if (res->wpa_ie_len) {			pos = wpa_supplicant_ie_txt(wpa_s, pos, end, "WPA",						    res->wpa_ie,						    res->wpa_ie_len);		}		if (res->rsn_ie_len) {			pos = wpa_supplicant_ie_txt(wpa_s, pos, end, "WPA2",						    res->rsn_ie,						    res->rsn_ie_len);		}		if (!res->wpa_ie_len && !res->rsn_ie_len &&		    res->caps & IEEE80211_CAP_PRIVACY)			pos += snprintf(pos, end - pos, "[WEP]");		if (res->caps & IEEE80211_CAP_IBSS)			pos += snprintf(pos, end - pos, "[IBSS]");		pos += snprintf(pos, end - pos, "\t%s",				wpa_ssid_txt(res->ssid, res->ssid_len));		pos += snprintf(pos, end - pos, "\n");	}	return pos - buf;}static int wpa_supplicant_ctrl_iface_select_network(	struct wpa_supplicant *wpa_s, char *cmd){	int id;	struct wpa_ssid *ssid;	/* cmd: "<network id>" or "any" */	if (strcmp(cmd, "any") == 0) {		wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");		ssid = wpa_s->conf->ssid;		while (ssid) {			ssid->disabled = 0;			ssid = ssid->next;		}		wpa_s->reassociate = 1;		wpa_supplicant_req_scan(wpa_s, 0, 0);		return 0;	}	id = atoi(cmd);	wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);	ssid = wpa_config_get_network(wpa_s->conf, id);	if (ssid == NULL) {

⌨️ 快捷键说明

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