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

📄 driver_nl80211.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct wpa_driver_nl80211_data *drv = eloop_ctx;	wpa_printf(MSG_DEBUG, "nl80211: Event message available");	cb = nl_cb_clone(drv->nl_cb);	if (!cb)		return;	nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, process_event, drv);	nl_recvmsgs(drv->nl_handle, cb);	nl_cb_put(cb);}static int wpa_driver_nl80211_get_ifflags_ifname(struct wpa_driver_nl80211_data *drv,					      const char *ifname, int *flags){	struct ifreq ifr;	os_memset(&ifr, 0, sizeof(ifr));	os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);	if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {		perror("ioctl[SIOCGIFFLAGS]");		return -1;	}	*flags = ifr.ifr_flags & 0xffff;	return 0;}/** * wpa_driver_nl80211_get_ifflags - Get interface flags (SIOCGIFFLAGS) * @drv: driver_nl80211 private data * @flags: Pointer to returned flags value * Returns: 0 on success, -1 on failure */static int wpa_driver_nl80211_get_ifflags(struct wpa_driver_nl80211_data *drv,					  int *flags){	return wpa_driver_nl80211_get_ifflags_ifname(drv, drv->ifname, flags);}static int wpa_driver_nl80211_set_ifflags_ifname(	struct wpa_driver_nl80211_data *drv,	const char *ifname, int flags){	struct ifreq ifr;	os_memset(&ifr, 0, sizeof(ifr));	os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);	ifr.ifr_flags = flags & 0xffff;	if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {		perror("SIOCSIFFLAGS");		return -1;	}	return 0;}/** * wpa_driver_nl80211_set_ifflags - Set interface flags (SIOCSIFFLAGS) * @drv: driver_nl80211 private data * @flags: New value for flags * Returns: 0 on success, -1 on failure */static int wpa_driver_nl80211_set_ifflags(struct wpa_driver_nl80211_data *drv,					  int flags){	return wpa_driver_nl80211_set_ifflags_ifname(drv, drv->ifname, flags);}/** * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain * @priv: driver_nl80211 private data * @alpha2_arg: country to which to switch to * Returns: 0 on success, -1 on failure * * This asks nl80211 to set the regulatory domain for given * country ISO / IEC alpha2. */static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg){	struct wpa_driver_nl80211_data *drv = priv;	char alpha2[3];	struct nl_msg *msg;	msg = nlmsg_alloc();	if (!msg)		goto nla_put_failure;	alpha2[0] = alpha2_arg[0];	alpha2[1] = alpha2_arg[1];	alpha2[2] = '\0';	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_REQ_SET_REG, 0);	NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);	if (send_and_recv_msgs(drv, msg, NULL, NULL))		return -EINVAL;	return 0;nla_put_failure:	return -EINVAL;}static int wpa_driver_nl80211_set_probe_req_ie(void *priv, const u8 *ies,					       size_t ies_len){	struct wpa_driver_nl80211_data *drv = priv;	struct nl_msg *msg;	int ret = -1;	msg = nlmsg_alloc();	if (!msg)		return -ENOMEM;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,		    NL80211_CMD_SET_MGMT_EXTRA_IE, 0);	NLA_PUT_U8(msg, NL80211_ATTR_MGMT_SUBTYPE, 4 /* ProbeReq */);	if (ies)		NLA_PUT(msg, NL80211_ATTR_IE, ies_len, ies);	ret = 0;	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);	ret = send_and_recv_msgs(drv, msg, NULL, NULL);	return ret;nla_put_failure:	return -ENOBUFS;}#ifdef CONFIG_CLIENT_MLMEstatic int nl80211_set_vif(struct wpa_driver_nl80211_data *drv,			   int drop_unencrypted, int userspace_mlme){#ifdef NL80211_CMD_SET_VIF	struct nl_msg *msg;	int ret = -1;	msg = nlmsg_alloc();	if (!msg)		return -ENOMEM;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,		    NL80211_CMD_SET_VIF, 0);	if (drop_unencrypted >= 0)		NLA_PUT_U8(msg, NL80211_ATTR_VIF_DROP_UNENCRYPTED,			   drop_unencrypted);	if (userspace_mlme >= 0)		NLA_PUT_U8(msg, NL80211_ATTR_VIF_USERSPACE_MLME,			   userspace_mlme);	ret = 0;	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);	ret = send_and_recv_msgs(drv, msg, NULL, NULL);	return ret;nla_put_failure:	return -ENOBUFS;#else /* NL80211_CMD_SET_VIF */	return -1;#endif /* NL80211_CMD_SET_VIF */}static int wpa_driver_nl80211_set_userspace_mlme(	struct wpa_driver_nl80211_data *drv, int enabled){	return nl80211_set_vif(drv, -1, enabled);}static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,				 int ifidx){	struct nl_msg *msg;	msg = nlmsg_alloc();	if (!msg)		goto nla_put_failure;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_DEL_INTERFACE, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx);	if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)		return;nla_put_failure:	wpa_printf(MSG_ERROR, "nl80211: Failed to remove interface.");}static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,				const char *ifname, enum nl80211_iftype iftype){	struct nl_msg *msg, *flags = NULL;	int ifidx, err;	int ret = -ENOBUFS;	msg = nlmsg_alloc();	if (!msg)		return -1;	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,		    0, NL80211_CMD_NEW_INTERFACE, 0);	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->ifname));	NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname);	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype);	if (iftype == NL80211_IFTYPE_MONITOR) {		flags = nlmsg_alloc();		if (!flags)			goto nla_put_failure;		NLA_PUT_FLAG(flags, NL80211_MNTR_FLAG_COOK_FRAMES);		err = nla_put_nested(msg, NL80211_ATTR_MNTR_FLAGS, flags);		nlmsg_free(flags);		if (err)			goto nla_put_failure;	}	ret = send_and_recv_msgs(drv, msg, NULL, NULL);	if (ret) {	nla_put_failure:		wpa_printf(MSG_ERROR, "nl80211: Failed to create interface %d",			   ret);		return ret;	}	ifidx = if_nametoindex(ifname);	if (ifidx <= 0)		return -1;	return ifidx;}static void handle_monitor_read(int sock, void *eloop_ctx, void *sock_ctx){	struct wpa_driver_nl80211_data *drv = eloop_ctx;	int len;	unsigned char buf[3000];	struct ieee80211_radiotap_iterator iter;	int ret;	int injected = 0, failed = 0, rxflags = 0;	struct ieee80211_rx_status rx_status;	len = recv(sock, buf, sizeof(buf), 0);	if (len < 0) {		perror("recv");		return;	}	if (ieee80211_radiotap_iterator_init(&iter, (void *) buf, len)) {		wpa_printf(MSG_DEBUG, "nl80211: received invalid radiotap "			   "frame");		return;	}	os_memset(&rx_status, 0, sizeof(rx_status));	while (1) {		ret = ieee80211_radiotap_iterator_next(&iter);		if (ret == -ENOENT)			break;		if (ret) {			wpa_printf(MSG_DEBUG, "nl80211: received invalid "				   "radiotap frame (%d)", ret);			return;		}		switch (iter.this_arg_index) {		case IEEE80211_RADIOTAP_FLAGS:			if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS)				len -= 4;			break;		case IEEE80211_RADIOTAP_RX_FLAGS:			rxflags = 1;			break;		case IEEE80211_RADIOTAP_TX_FLAGS:			injected = 1;			failed = le_to_host16((*(u16 *) iter.this_arg)) &				IEEE80211_RADIOTAP_F_TX_FAIL;			break;		case IEEE80211_RADIOTAP_DATA_RETRIES:			break;		case IEEE80211_RADIOTAP_CHANNEL:			/* TODO convert from freq/flags to channel number			 * rx_status.channel = XXX;			*/			break;		case IEEE80211_RADIOTAP_RATE:			break;		case IEEE80211_RADIOTAP_DB_ANTSIGNAL:			rx_status.ssi = *iter.this_arg;			break;		}	}	if (rxflags && injected)		return;	if (!injected) {		wpa_supplicant_sta_rx(drv->ctx, buf + iter.max_length,				      len - iter.max_length, &rx_status);	} else if (failed) {		/* TX failure callback */	} else {		/* TX success (ACK) callback */	}}static int wpa_driver_nl80211_create_monitor_interface(	struct wpa_driver_nl80211_data *drv){	char buf[IFNAMSIZ];	struct sockaddr_ll ll;	int optval, flags;	socklen_t optlen;	os_snprintf(buf, IFNAMSIZ, "mon.%s", drv->ifname);	buf[IFNAMSIZ - 1] = '\0';	drv->monitor_ifidx =		nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR);	if (drv->monitor_ifidx < 0)		return -1;	if (wpa_driver_nl80211_get_ifflags_ifname(drv, buf, &flags) != 0 ||	    wpa_driver_nl80211_set_ifflags_ifname(drv, buf, flags | IFF_UP) !=	    0) {		wpa_printf(MSG_ERROR, "nl80211: Could not set interface '%s' "			   "UP", buf);		goto error;	}	os_memset(&ll, 0, sizeof(ll));	ll.sll_family = AF_PACKET;	ll.sll_ifindex = drv->monitor_ifidx;	drv->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));	if (drv->monitor_sock < 0) {		perror("socket[PF_PACKET,SOCK_RAW]");		goto error;	}	if (bind(drv->monitor_sock, (struct sockaddr *) &ll,		 sizeof(ll)) < 0) {		perror("monitor socket bind");		goto error;	}	optlen = sizeof(optval);	optval = 20;	if (setsockopt	    (drv->monitor_sock, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) {		perror("Failed to set socket priority");		goto error;	}	if (eloop_register_read_sock(drv->monitor_sock, handle_monitor_read,				     drv, NULL)) {		wpa_printf(MSG_ERROR, "nl80211: Could not register monitor "			   "read socket");		goto error;	}	return 0; error:	nl80211_remove_iface(drv, drv->monitor_ifidx);	return -1;}#endif /* CONFIG_CLIENT_MLME *//** * wpa_driver_nl80211_init - Initialize nl80211 driver interface * @ctx: context to be used when calling wpa_supplicant functions, * e.g., wpa_supplicant_event() * @ifname: interface name, e.g., wlan0 * Returns: Pointer to private data, %NULL on failure */static void * wpa_driver_nl80211_init(void *ctx, const char *ifname){	int s, ret;	struct sockaddr_nl local;	struct wpa_driver_nl80211_data *drv;	drv = os_zalloc(sizeof(*drv));	if (drv == NULL)		return NULL;	drv->ctx = ctx;	os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));	drv->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);	if (drv->nl_cb == NULL) {		wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "			   "callbacks");		goto err1;	}	drv->nl_handle = nl_handle_alloc_cb(drv->nl_cb);	if (drv->nl_handle == NULL) {		wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "			   "callbacks");		goto err2;	}	if (genl_connect(drv->nl_handle)) {		wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "			   "netlink");		goto err3;	}	drv->nl_cache = genl_ctrl_alloc_cache(drv->nl_handle);	if (drv->nl_cache == NULL) {		wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "			   "netlink cache");		goto err3;	}	drv->nl80211 = genl_ctrl_search_by_name(drv->nl_cache, "nl80211");	if (drv->nl80211 == NULL) {		wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "			   "found");		goto err4;	}	ret = nl_get_multicast_id(drv, "nl80211", "scan");	if (ret >= 0)		ret = nl_socket_add_membership(drv->nl_handle, ret);	if (ret < 0) {		wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "			   "membership for scan events: %d (%s)",			   ret, strerror(-ret));		goto err4;	}	eloop_register_read_sock(nl_socket_get_fd(drv->nl_handle),				 wpa_driver_nl80211_event_receive, drv, ctx);	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);	if (drv->ioctl_sock < 0) {		perror("socket(PF_INET,SOCK_DGRAM)");		goto err5;	}	s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);	if (s < 0) {		perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");		goto err6;	}	os_memset(&local, 0, sizeof(local));	local.nl_family = AF_NETLINK;	local.nl_groups = RTMGRP_LINK;	if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {		perror("bind(netlink)");		close(s);		goto err6;	}	eloop_register_read_sock(s, wpa_driver_nl80211_event_receive_wext, drv,				 ctx);	drv->wext_event_sock = s;	wpa_driver_nl80211_finish_drv_init(drv);	return drv;err6:	close(drv->ioctl_sock);err5:	genl_family_put(drv->nl80211);err4:	nl_cache_free(drv->nl_cache);err3:	nl_handle_destroy(drv->nl_handle);err2:	nl_cb_put(drv->nl_cb);err1:	os_free(drv);	return NULL;}static voidwpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv){	int flags;	if (wpa_driver_nl80211_get_ifflags(drv, &flags) != 0)		printf("Could not get interface '%s' flags\n", drv->ifname);

⌨️ 快捷键说明

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