2
* WPA Supplicant - Layer2 packet handling
3
* Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation.
9
* Alternatively, this software may be distributed under the terms of BSD
12
* See README and COPYING for more details.
18
#ifndef CONFIG_NATIVE_WINDOWS
19
#include <sys/ioctl.h>
20
#endif /* CONFIG_NATIVE_WINDOWS */
24
#ifndef CONFIG_WINPCAP
27
#else /* USE_DNET_PCAP */
29
#include <sys/types.h>
30
#include <sys/socket.h>
31
#include <netinet/in.h>
32
#include <netpacket/packet.h>
34
#endif /* USE_DNET_PCAP */
38
#include "l2_packet.h"
41
struct l2_packet_data {
44
#ifndef CONFIG_WINPCAP
47
#else /* USE_DNET_PCAP */
48
int fd; /* packet socket for EAPOL frames */
49
#endif /* USE_DNET_PCAP */
51
u8 own_addr[ETH_ALEN];
52
void (*rx_callback)(void *ctx, unsigned char *src_addr,
53
unsigned char *buf, size_t len);
54
void *rx_callback_ctx;
55
int rx_l2_hdr; /* whether to include layer 2 (Ethernet) header in calls
60
int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr)
62
memcpy(addr, l2->own_addr, ETH_ALEN);
67
void l2_packet_set_rx_l2_hdr(struct l2_packet_data *l2, int rx_l2_hdr)
69
l2->rx_l2_hdr = rx_l2_hdr;
75
#ifndef CONFIG_WINPCAP
76
static int l2_packet_init_libdnet(struct l2_packet_data *l2)
80
l2->eth = eth_open(l2->ifname);
82
printf("Failed to open interface '%s'.\n", l2->ifname);
87
if (eth_get(l2->eth, &own_addr) < 0) {
88
printf("Failed to get own hw address from interface '%s'.\n",
95
memcpy(l2->own_addr, own_addr.data, ETH_ALEN);
102
#ifdef CONFIG_WINPCAP
103
int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
106
int l2_packet_send(struct l2_packet_data *l2, u8 *buf, size_t len)
108
#ifdef CONFIG_WINPCAP
109
return pcap_sendpacket(l2->pcap, buf, len);
111
return eth_send(l2->eth, buf, len);
116
static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx)
118
struct l2_packet_data *l2 = eloop_ctx;
119
pcap_t *pcap = sock_ctx;
120
struct pcap_pkthdr hdr;
121
const u_char *packet;
122
struct l2_ethhdr *ethhdr;
126
packet = pcap_next(pcap, &hdr);
128
if (packet == NULL || hdr.caplen < sizeof(*ethhdr))
131
ethhdr = (struct l2_ethhdr *) packet;
133
buf = (unsigned char *) ethhdr;
136
buf = (unsigned char *) (ethhdr + 1);
137
len = hdr.caplen - sizeof(*ethhdr);
139
l2->rx_callback(l2->rx_callback_ctx, ethhdr->h_source, buf, len);
143
#ifdef CONFIG_WINPCAP
144
static void l2_packet_receive_timeout(void *eloop_ctx, void *timeout_ctx)
146
struct l2_packet_data *l2 = eloop_ctx;
147
pcap_t *pcap = timeout_ctx;
148
/* Register new timeout before calling l2_packet_receive() since
149
* receive handler may free this l2_packet instance (which will
150
* cancel this timeout). */
151
eloop_register_timeout(0, 100000, l2_packet_receive_timeout,
153
l2_packet_receive(-1, eloop_ctx, timeout_ctx);
155
#endif /* CONFIG_WINPCAP */
158
static int l2_packet_init_libpcap(struct l2_packet_data *l2,
159
unsigned short protocol)
161
bpf_u_int32 pcap_maskp, pcap_netp;
162
char pcap_filter[100], pcap_err[PCAP_ERRBUF_SIZE];
163
struct bpf_program pcap_fp;
165
pcap_lookupnet(l2->ifname, &pcap_netp, &pcap_maskp, pcap_err);
166
l2->pcap = pcap_open_live(l2->ifname, 2500, 0, 10, pcap_err);
167
if (l2->pcap == NULL) {
168
fprintf(stderr, "pcap_open_live: %s\n", pcap_err);
169
fprintf(stderr, "ifname='%s'\n", l2->ifname);
172
#ifndef CONFIG_WINPCAP
173
if (pcap_datalink(l2->pcap) != DLT_EN10MB) {
174
if (pcap_set_datalink(l2->pcap, DLT_EN10MB) < 0) {
175
fprintf(stderr, "pcap_set_datalinke(DLT_EN10MB): %s\n",
176
pcap_geterr(l2->pcap));
180
#endif /* CONFIG_WINPCAP */
181
snprintf(pcap_filter, sizeof(pcap_filter),
182
"ether dst " MACSTR " and ether proto 0x%x",
183
MAC2STR(l2->own_addr), protocol);
184
if (pcap_compile(l2->pcap, &pcap_fp, pcap_filter, 1, pcap_netp) < 0)
186
fprintf(stderr, "pcap_compile: %s\n",
187
pcap_geterr(l2->pcap));
191
if (pcap_setfilter(l2->pcap, &pcap_fp) < 0) {
192
fprintf(stderr, "pcap_setfilter: %s\n",
193
pcap_geterr(l2->pcap));
197
pcap_freecode(&pcap_fp);
200
* When libpcap uses BPF we must enable "immediate mode" to
201
* receive frames right away; otherwise the system may
202
* buffer them for us.
206
if (ioctl(pcap_fileno(l2->pcap), BIOCIMMEDIATE, &on) < 0) {
207
fprintf(stderr, "%s: cannot enable immediate mode on "
208
"interface %s: %s\n",
209
__func__, l2->ifname, strerror(errno));
210
/* XXX should we fail? */
213
#endif /* BIOCIMMEDIATE */
215
#ifdef CONFIG_WINPCAP
216
eloop_register_timeout(0, 100000, l2_packet_receive_timeout,
219
eloop_register_read_sock(pcap_get_selectable_fd(l2->pcap),
220
l2_packet_receive, l2, l2->pcap);
228
struct l2_packet_data * l2_packet_init(
229
const char *ifname, const u8 *own_addr, unsigned short protocol,
230
void (*rx_callback)(void *ctx, unsigned char *src_addr,
231
unsigned char *buf, size_t len),
232
void *rx_callback_ctx)
234
struct l2_packet_data *l2;
236
l2 = malloc(sizeof(struct l2_packet_data));
239
memset(l2, 0, sizeof(*l2));
240
strncpy(l2->ifname, ifname, sizeof(l2->ifname));
241
l2->rx_callback = rx_callback;
242
l2->rx_callback_ctx = rx_callback_ctx;
244
#ifdef CONFIG_WINPCAP
246
memcpy(l2->own_addr, own_addr, ETH_ALEN);
248
if (l2_packet_init_libdnet(l2))
252
if (l2_packet_init_libpcap(l2, protocol)) {
253
#ifndef CONFIG_WINPCAP
264
void l2_packet_deinit(struct l2_packet_data *l2)
270
pcap_close(l2->pcap);
271
#ifdef CONFIG_WINPCAP
272
eloop_cancel_timeout(l2_packet_receive_timeout, l2, l2->pcap);
280
#else /* USE_DNET_PCAP */
282
int l2_packet_send(struct l2_packet_data *l2, u8 *buf, size_t len)
285
ret = send(l2->fd, buf, len, 0);
287
perror("l2_packet_send - send");
292
static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx)
294
struct l2_packet_data *l2 = eloop_ctx;
297
struct l2_ethhdr *ethhdr;
301
res = recv(sock, buf, sizeof(buf), 0);
303
perror("l2_packet_receive - recv");
306
if (res < sizeof(*ethhdr)) {
307
printf("l2_packet_receive: Dropped too short %d packet\n",
312
ethhdr = (struct l2_ethhdr *) buf;
315
pos = (unsigned char *) buf;
318
pos = (unsigned char *) (ethhdr + 1);
319
len = res - sizeof(*ethhdr);
321
l2->rx_callback(l2->rx_callback_ctx, ethhdr->h_source, pos, len);
325
struct l2_packet_data * l2_packet_init(
326
const char *ifname, const u8 *own_addr, unsigned short protocol,
327
void (*rx_callback)(void *ctx, unsigned char *src_addr,
328
unsigned char *buf, size_t len),
329
void *rx_callback_ctx)
331
struct l2_packet_data *l2;
333
struct sockaddr_ll ll;
335
l2 = malloc(sizeof(struct l2_packet_data));
338
memset(l2, 0, sizeof(*l2));
339
strncpy(l2->ifname, ifname, sizeof(l2->ifname));
340
l2->rx_callback = rx_callback;
341
l2->rx_callback_ctx = rx_callback_ctx;
343
l2->fd = socket(PF_PACKET, SOCK_RAW, htons(protocol));
345
perror("socket(PF_PACKET, SOCK_RAW)");
349
strncpy(ifr.ifr_name, l2->ifname, sizeof(ifr.ifr_name));
350
if (ioctl(l2->fd, SIOCGIFINDEX, &ifr) < 0) {
351
perror("ioctl[SIOCGIFINDEX]");
357
memset(&ll, 0, sizeof(ll));
358
ll.sll_family = PF_PACKET;
359
ll.sll_ifindex = ifr.ifr_ifindex;
360
ll.sll_protocol = htons(protocol);
361
if (bind(l2->fd, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
362
perror("bind[PF_PACKET]");
368
if (ioctl(l2->fd, SIOCGIFHWADDR, &ifr) < 0) {
369
perror("ioctl[SIOCGIFHWADDR]");
374
memcpy(l2->own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
376
eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL);
382
void l2_packet_deinit(struct l2_packet_data *l2)
388
eloop_unregister_read_sock(l2->fd);
395
#endif /* USE_DNET_PCAP */