当前位置: 首页 > article >正文

wpa_supplicant二层包收发

添加 wlan 接口时会调用wpa_supplicant_init_iface

\wpa_supplicant\wpa_supplicant.c

\src\l2_packet\l2_packet_linux.c

这里面就是初始化一个 PF_PACKET socket 文件描述符,然后向 eloop 注册读事件,在 bind 时绑定了 wlan 接口地址,因此可以使用这个 socket 文件描述符对指定 wlan 接口收发二层数据包



struct l2_packet_data * l2_packet_init(
	const char *ifname, const u8 *own_addr, unsigned short protocol,
	void (*rx_callback)(void *ctx, const u8 *src_addr,
			    const u8 *buf, size_t len),
	void *rx_callback_ctx, int l2_hdr)
{
	struct l2_packet_data *l2;
	struct ifreq ifr;
	struct sockaddr_ll ll;

	l2 = os_zalloc(sizeof(struct l2_packet_data));
	if (l2 == NULL)
		return NULL;
	os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname));
	l2->rx_callback = rx_callback;
	l2->rx_callback_ctx = rx_callback_ctx;
	l2->l2_hdr = l2_hdr;
#ifndef CONFIG_NO_LINUX_PACKET_SOCKET_WAR
	l2->fd_br_rx = -1;
#endif /* CONFIG_NO_LINUX_PACKET_SOCKET_WAR */

	l2->fd = socket(PF_PACKET, l2_hdr ? SOCK_RAW : SOCK_DGRAM,
			htons(protocol));
	if (l2->fd < 0) {
		wpa_printf(MSG_ERROR, "%s: socket(PF_PACKET): %s",
			   __func__, strerror(errno));
		os_free(l2);
		return NULL;
	}
	os_memset(&ifr, 0, sizeof(ifr));
	os_strlcpy(ifr.ifr_name, l2->ifname, sizeof(ifr.ifr_name));
	if (ioctl(l2->fd, SIOCGIFINDEX, &ifr) < 0) {
		wpa_printf(MSG_ERROR, "%s: ioctl[SIOCGIFINDEX]: %s",
			   __func__, strerror(errno));
		close(l2->fd);
		os_free(l2);
		return NULL;
	}
	l2->ifindex = ifr.ifr_ifindex;

	os_memset(&ll, 0, sizeof(ll));
	ll.sll_family = PF_PACKET;
	ll.sll_ifindex = ifr.ifr_ifindex;
	ll.sll_protocol = htons(protocol);
	if (rx_callback &&
	    bind(l2->fd, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
		wpa_printf(MSG_ERROR, "%s: bind[PF_PACKET]: %s",
			   __func__, strerror(errno));
		close(l2->fd);
		os_free(l2);
		return NULL;
	}

	if (ioctl(l2->fd, SIOCGIFHWADDR, &ifr) < 0) {
		wpa_printf(MSG_ERROR, "%s: ioctl[SIOCGIFHWADDR]: %s",
			   __func__, strerror(errno));
		close(l2->fd);
		os_free(l2);
		return NULL;
	}
	os_memcpy(l2->own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);

	if (rx_callback)
		eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL);

	return l2;
}


http://www.kler.cn/a/593686.html

相关文章:

  • Gone gRPC 组件使用指南
  • Android BLE 权限管理
  • 论文阅读 EEGNet
  • Vue:添加响应式数据
  • 使用git托管项目
  • 【DeepSeekR1】怎样清除mssql的日志文件?
  • 服务的拆分数据的迁移
  • ambiq apollo3 Flash实例程序注释
  • Java 实现两个线程交替打印AB的几种方式
  • 从零开始搭建向量数据库:基于 Xinference 和 Milvus 的文本搜索实践
  • 机器学习是怎么一步一步由神经网络发展到今天的Transformer架构的?
  • 2025 使用docker部署ubuntu24容器并且需要ubuntu24容器能通过ssh登录SSH 登录的Ubuntu24容器
  • Modern C++处理 Hooks 机制
  • Datawhale大语言模型-Transformer以及模型详细配置
  • HttpClient通讯时间过久
  • MiniMax GenAI 可观测性分析:基于阿里云 SelectDB 构建 PB 级别日志系统
  • python采集小红书笔记详情API接口,json数据示例分享
  • 理工超市-多用户注册
  • 【C++模板】
  • Linux--进程创建