nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 * Copyright (c) 2010 Andrea Bittau <bittau@cs.stanford.edu>
3 *
4 * OS dependent API for using card via a pcap file.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20  
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <assert.h>
30 #include <sys/select.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <err.h>
34  
35 #include "osdep.h"
36 #include "pcap.h"
37 #include "radiotap/radiotap_iter.h"
38  
39 struct priv_file {
40 int pf_fd;
41 int pf_chan;
42 int pf_rate;
43 int pf_dtl;
44 unsigned char pf_mac[6];
45 };
46  
47 static int file_read(struct wif *wi, unsigned char *h80211, int len,
48 struct rx_info *ri)
49 {
50 struct priv_file *pf = wi_priv(wi);
51 struct pcap_pkthdr pkh;
52 int rc;
53 unsigned char buf[4096];
54 int off = 0;
55 struct ieee80211_radiotap_header *rh;
56 struct ieee80211_radiotap_iterator iter;
57  
58 rc = read(pf->pf_fd, &pkh, sizeof(pkh));
59 if (rc != sizeof(pkh))
60 return -1;
61  
62 if (pkh.caplen > sizeof(buf)) {
63 printf("Bad caplen %d\n", pkh.caplen);
64 return 0;
65 }
66  
67 assert(pkh.caplen <= sizeof(buf));
68  
69 rc = read(pf->pf_fd, buf, pkh.caplen);
70 if (rc != (int) pkh.caplen)
71 return -1;
72  
73 if (ri)
74 memset(ri, 0, sizeof(*ri));
75  
76 switch (pf->pf_dtl) {
77 case LINKTYPE_IEEE802_11:
78 off = 0;
79 break;
80  
81 case LINKTYPE_RADIOTAP_HDR:
82 rh = (struct ieee80211_radiotap_header*) buf;
83 off = le16_to_cpu(rh->it_len);
84  
85 if (ieee80211_radiotap_iterator_init(&iter, rh, rc, NULL) < 0)
86 return -1;
87  
88 while (ieee80211_radiotap_iterator_next(&iter) >= 0) {
89 switch (iter.this_arg_index) {
90 case IEEE80211_RADIOTAP_FLAGS:
91 if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS)
92 rc -= 4;
93 break;
94 }
95 }
96 break;
97  
98 case LINKTYPE_PRISM_HEADER:
99 if (buf[7] == 0x40)
100 off = 0x40;
101 else
102 off = *((int *)(buf + 4));
103  
104 rc -= 4;
105 break;
106  
107 case LINKTYPE_PPI_HDR:
108 off = le16_to_cpu(*(unsigned short *)(buf + 2));
109  
110 /* for a while Kismet logged broken PPI headers */
111 if (off == 24 && le16_to_cpu(*(unsigned short *)(buf + 8)) == 2 )
112 off = 32;
113  
114 break;
115  
116 case LINKTYPE_ETHERNET:
117 printf("Ethernet packets\n");
118 return 0;
119  
120 default:
121 errx(1, "Unknown DTL %d", pf->pf_dtl);
122 break;
123 }
124  
125 rc -= off;
126 assert(rc >= 0);
127  
128 if (rc > len)
129 rc = len;
130  
131 memcpy(h80211, &buf[off], rc);
132  
133 return rc;
134 }
135  
136 static int file_get_mac(struct wif *wi, unsigned char *mac)
137 {
138 struct priv_file *pn = wi_priv(wi);
139  
140 memcpy(mac, pn->pf_mac, sizeof(pn->pf_mac));
141  
142 return 0;
143 }
144  
145 static int file_write(struct wif *wi, unsigned char *h80211, int len,
146 struct tx_info *ti)
147 {
148 struct priv_file *pn = wi_priv(wi);
149  
150 if (h80211 && ti && pn) {}
151  
152 return len;
153 }
154  
155 static int file_set_channel(struct wif *wi, int chan)
156 {
157 struct priv_file *pf = wi_priv(wi);
158  
159 pf->pf_chan = chan;
160  
161 return 0;
162 }
163  
164 static int file_get_channel(struct wif *wi)
165 {
166 struct priv_file *pf = wi_priv(wi);
167  
168 return pf->pf_chan;
169 }
170  
171 static int file_set_rate(struct wif *wi, int rate)
172 {
173 struct priv_file *pf = wi_priv(wi);
174  
175 pf->pf_rate = rate;
176  
177 return 0;
178 }
179  
180 static int file_get_rate(struct wif *wi)
181 {
182 struct priv_file *pf = wi_priv(wi);
183  
184 return pf->pf_rate;
185 }
186  
187 static int file_get_monitor(struct wif *wi)
188 {
189 if (wi) {}
190  
191 return 1;
192 }
193  
194 static void file_close(struct wif *wi)
195 {
196 struct priv_file *pn = wi_priv(wi);
197  
198 if (pn->pf_fd)
199 close(pn->pf_fd);
200  
201 free(wi);
202 }
203  
204 static int file_fd(struct wif *wi)
205 {
206 struct priv_file *pf = wi_priv(wi);
207  
208 return pf->pf_fd;
209 }
210  
211 struct wif *file_open(char *iface)
212 {
213 struct wif *wi;
214 struct priv_file *pf;
215 int fd;
216 struct pcap_file_header pfh;
217 int rc;
218  
219 if (strncmp(iface, "file://", 7) != 0)
220 return NULL;
221  
222 /* setup wi struct */
223 wi = wi_alloc(sizeof(*pf));
224 if (!wi)
225 return NULL;
226  
227 wi->wi_read = file_read;
228 wi->wi_write = file_write;
229 wi->wi_set_channel = file_set_channel;
230 wi->wi_get_channel = file_get_channel;
231 wi->wi_set_rate = file_set_rate;
232 wi->wi_get_rate = file_get_rate;
233 wi->wi_close = file_close;
234 wi->wi_fd = file_fd;
235 wi->wi_get_mac = file_get_mac;
236 wi->wi_get_monitor = file_get_monitor;
237  
238 pf = wi_priv(wi);
239  
240 fd = open(iface + 7, O_RDONLY);
241 if (fd == -1)
242 err(1, "open()");
243  
244 pf->pf_fd = fd;
245  
246 if ((rc = read(fd, &pfh, sizeof(pfh))) != sizeof(pfh))
247 goto __err;
248  
249 if (pfh.magic != TCPDUMP_MAGIC)
250 goto __err;
251  
252 if (pfh.version_major != PCAP_VERSION_MAJOR
253 || pfh.version_minor != PCAP_VERSION_MINOR)
254 goto __err;
255  
256 pf->pf_dtl = pfh.linktype;
257  
258 return wi;
259  
260 __err:
261 wi_close(wi);
262 return (struct wif*) -1;
263 }