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

📄 l2_packet_linux.c

📁 一个Linux下无线网卡的设置工具
💻 C
字号:
/* * WPA Supplicant - Layer2 packet handling with Linux packet sockets * Copyright (c) 2003-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 <sys/ioctl.h>#include <errno.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netpacket/packet.h>#include <net/if.h>#include <arpa/inet.h>#include "common.h"#include "eloop.h"#include "l2_packet.h"struct l2_packet_data {	int fd; /* packet socket for EAPOL frames */	char ifname[IFNAMSIZ + 1];	int ifindex;	u8 own_addr[ETH_ALEN];	void (*rx_callback)(void *ctx, const u8 *src_addr,			    const u8 *buf, size_t len);	void *rx_callback_ctx;	int l2_hdr; /* whether to include layer 2 (Ethernet) header data		     * buffers */};int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr){	memcpy(addr, l2->own_addr, ETH_ALEN);	return 0;}int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto,		   const u8 *buf, size_t len){	int ret;	if (l2 == NULL)		return -1;	if (l2->l2_hdr) {		ret = send(l2->fd, buf, len, 0);		if (ret < 0)			perror("l2_packet_send - send");	} else {		struct sockaddr_ll ll;		memset(&ll, 0, sizeof(ll));		ll.sll_family = AF_PACKET;		ll.sll_ifindex = l2->ifindex;		ll.sll_protocol = htons(proto);		ll.sll_halen = ETH_ALEN;		memcpy(ll.sll_addr, dst_addr, ETH_ALEN);		ret = sendto(l2->fd, buf, len, 0, (struct sockaddr *) &ll,			     sizeof(ll));		if (ret < 0)			perror("l2_packet_send - sendto");	}	return ret;}static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx){	struct l2_packet_data *l2 = eloop_ctx;	u8 buf[2300];	int res;	struct sockaddr_ll ll;	socklen_t fromlen;	memset(&ll, 0, sizeof(ll));	fromlen = sizeof(ll);	res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &ll,		       &fromlen);	if (res < 0) {		perror("l2_packet_receive - recvfrom");		return;	}	l2->rx_callback(l2->rx_callback_ctx, ll.sll_addr, buf, res);}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 = malloc(sizeof(struct l2_packet_data));	if (l2 == NULL)		return NULL;	memset(l2, 0, sizeof(*l2));	strncpy(l2->ifname, ifname, sizeof(l2->ifname));	l2->rx_callback = rx_callback;	l2->rx_callback_ctx = rx_callback_ctx;	l2->l2_hdr = l2_hdr;	l2->fd = socket(PF_PACKET, l2_hdr ? SOCK_RAW : SOCK_DGRAM,			htons(protocol));	if (l2->fd < 0) {		perror("socket(PF_PACKET)");		free(l2);		return NULL;	}	strncpy(ifr.ifr_name, l2->ifname, sizeof(ifr.ifr_name));	if (ioctl(l2->fd, SIOCGIFINDEX, &ifr) < 0) {		perror("ioctl[SIOCGIFINDEX]");		close(l2->fd);		free(l2);		return NULL;	}	l2->ifindex = ifr.ifr_ifindex;	memset(&ll, 0, sizeof(ll));	ll.sll_family = PF_PACKET;	ll.sll_ifindex = ifr.ifr_ifindex;	ll.sll_protocol = htons(protocol);	if (bind(l2->fd, (struct sockaddr *) &ll, sizeof(ll)) < 0) {		perror("bind[PF_PACKET]");		close(l2->fd);		free(l2);		return NULL;	}	if (ioctl(l2->fd, SIOCGIFHWADDR, &ifr) < 0) {		perror("ioctl[SIOCGIFHWADDR]");		close(l2->fd);		free(l2);		return NULL;	}	memcpy(l2->own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);	eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL);	return l2;}void l2_packet_deinit(struct l2_packet_data *l2){	if (l2 == NULL)		return;	if (l2->fd >= 0) {		eloop_unregister_read_sock(l2->fd);		close(l2->fd);	}			free(l2);}int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len){	int s;	struct ifreq ifr;	struct sockaddr_in *saddr;	s = socket(PF_INET, SOCK_DGRAM, 0);	if (s < 0) {		perror("socket");		return -1;	}	memset(&ifr, 0, sizeof(ifr));	strncpy(ifr.ifr_name, l2->ifname, sizeof(ifr.ifr_name));	if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {		perror("ioctl[SIOCGIFADDR]");		close(s);		return -1;	}	close(s);	saddr = (struct sockaddr_in *) &ifr.ifr_addr;	if (saddr->sin_family != AF_INET)		return -1;	snprintf(buf, len, "%s", inet_ntoa(saddr->sin_addr));	return 0;}void l2_packet_notify_auth_start(struct l2_packet_data *l2){}

⌨️ 快捷键说明

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