-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinterface.c
154 lines (121 loc) · 2.84 KB
/
interface.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "interface.h"
struct priv_if {
pcap_t *fd_in;
pcap_t *fd_out;
int rate;
};
static void *mi_priv(struct mif *mi)
{
return mi->mi_priv;
}
static void mi_close(struct mif *mi)
{
struct priv_if *pi = mi_priv(mi);
if (pi->fd_in)
pcap_close(pi->fd_in);
if (pi->fd_out)
pcap_close(pi->fd_out);
}
static int mi_read(struct mif *mi, unsigned char *buf,
int count, struct rx_info *ri)
{
return 0;
}
static int mi_write(struct mif *mi, unsigned char *buf,
int count, struct tx_info *ti)
{
struct priv_if *dev = mi_priv(mi);
unsigned char tmpbuf[4096];
unsigned char rate;
int ret;
unsigned char u8aRadiotap[] = {
0x00, 0x00, // <-- radiotap version
0x09, 0x00, // <- radiotap header length
0x04, 0x00, 0x00, 0x00, // <-- bitmap
0x00, // <-- rate
};
if ((unsigned) count > sizeof(tmpbuf) - 22)
return -1;
if (ti)
rate = ti->ti_rate;
else
rate = dev->rate;
u8aRadiotap[8] = rate;
memcpy(tmpbuf, u8aRadiotap, sizeof (u8aRadiotap));
memcpy(tmpbuf + sizeof (u8aRadiotap), buf, count);
count += sizeof (u8aRadiotap);
buf = tmpbuf;
ret = pcap_inject(dev->fd_out, buf, count);
if (ret == -1)
pcap_perror(dev->fd_out, 0);
return ret;
}
pcap_t* mi_fd_in(struct mif *mi)
{
struct priv_if *pi = mi_priv(mi);
return pi->fd_in;
}
pcap_t* mi_fd_out(struct mif *mi)
{
struct priv_if *pi = mi_priv(mi);
return pi->fd_out;
}
struct mif *mi_alloc(int sz)
{
struct mif *mi;
void *priv;
/* Allocate wif & private state */
mi = malloc(sizeof(*mi));
if (!mi)
return NULL;
memset(mi, 0, sizeof(*mi));
priv = malloc(sz);
if (!priv) {
free(mi);
return NULL;
}
memset(priv, 0, sz);
mi->mi_priv = priv;
return mi;
}
struct mif *mi_open(char *iface)
{
struct mif *mi;
struct priv_if *pi;
pcap_t *pkt_in, *pkt_out;
char errbuf[PCAP_ERRBUF_SIZE];
/* setup mi struct */
mi = mi_alloc(sizeof(*pi));
if (!mi)
return NULL;
mi->read = mi_read;
mi->write = mi_write;
mi->close = mi_close;
// for pkt in
pkt_in = pcap_open_live(iface, 4096, 1, 10, errbuf);
if (pkt_in == NULL) {
printf("Unable to open interface %s in pcap: %s\n", iface, errbuf);
return NULL;
}
if (pcap_datalink(pkt_in) != DLT_IEEE802_11_RADIO) {
printf("Device %s doesn't provide 80211 radiotap header\n", iface);
return NULL;
}
if (pcap_setnonblock(pkt_in, 1, errbuf) == -1) {
printf("Device %s doesn't set non-blocking mode\n", iface);
return NULL;
}
// for pkt out
pkt_out = pcap_open_live(iface, 4096, 1, 10, errbuf);
if (pkt_out == NULL) {
printf("Unable to open interface %s in pcap: %s\n", iface, errbuf);
return NULL;
}
pi = mi_priv(mi);
pi->fd_in = pkt_in;
pi->fd_out = pkt_out;
return mi;
}