summaryrefslogtreecommitdiff
path: root/noncore/net/wellenreiter/libwellenreiter/source/sniff.cc
Unidiff
Diffstat (limited to 'noncore/net/wellenreiter/libwellenreiter/source/sniff.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/wellenreiter/libwellenreiter/source/sniff.cc419
1 files changed, 0 insertions, 419 deletions
diff --git a/noncore/net/wellenreiter/libwellenreiter/source/sniff.cc b/noncore/net/wellenreiter/libwellenreiter/source/sniff.cc
deleted file mode 100644
index 0616a7e..0000000
--- a/noncore/net/wellenreiter/libwellenreiter/source/sniff.cc
+++ b/dev/null
@@ -1,419 +0,0 @@
1/*
2 * rfmon mode sniffer
3 *
4 * $Id$
5 */
6
7#include "sniff.hh"
8#include "ieee802_11.hh"
9#include "extract.hh"
10#include "wl_log.hh"
11#include "wl_types.hh"
12#include "wl_proto.hh"
13#include "cardmode.hh"
14
15int start_sniffer(const char *device, int cardtype )
16{
17
18 /* This function initialize the sniffing
19 1. Check for lo interface
20 2. bring it into promsicous mode and UP
21 3. bring device into rfmon mode
22 start the pcap sniffing process.
23 */
24
25 /* Do we have the device name ? */
26 if(device == NULL)
27 {
28 wl_logerr("start_sniffer, parameter \"device\" is empty, please check your config");
29 return 0;
30 }
31
32 /* Some Linux System does not have a loopback device lo with 127.0.0.1 so sockets could
33 not made correctly, let the proggie check that and proceed only if it exists. */
34 if (!check_loopback())
35 {
36 wl_logerr("start_sniffer, check_loopback failed, cannot continue without a loopback");
37 return 0;
38 }
39
40 /* Set the card into regulary promiscous mode first and set the UP flag, in case no ip
41 was given. It would work without the promisc flags but i dont like this */
42 if (!card_set_promisc_up(device))
43 {
44 wl_logerr("start_sniffer, card_set_promisc_up failed, cannot continue");
45 return 0;
46 }
47
48 /* Set card into the rfmon/monitoring mode */
49 if (!card_into_monitormode(device,cardtype))
50 {
51 wl_logerr("start_sniffer, cannot put wireless card into monitoring mode, aborting");
52 return 0;
53 }
54
55 /* setup pcap handle, used for the packet decoding etc. */
56 if((handletopcap = pcap_open_live((char *) device, BUFSIZ, 1, 0, NULL)) == NULL)
57 {
58 wl_logerr("pcap_open_live() failed: %s", strerror(errno));
59 return 0;
60 }
61
62#ifdef HAVE_PCAP_NONBLOCK
63 pcap_setnonblock(handletopcap, 1, NULL);
64#endif
65 return 1;
66}
67
68
69int stop_sniffer(const char *device, int cardtype)
70{
71 /* This function terminates the sniffing
72 1. get the device state
73 2. remove the rfmon state
74 3. Remove the promisc state
75 start the pcap sniffing process.
76
77 */
78
79 /* Do we really have at least a lo interface with the 127.0.0.1 ? */
80 return 0;
81
82}
83
84
85/* Main function, checks packets */
86void process_packets(const struct pcap_pkthdr *pkthdr,
87 const unsigned char *packet,
88 char *guihost,
89 int guiport)
90{
91 unsigned int caplen = pkthdr->caplen;
92 unsigned int length = pkthdr->len;
93 u_int16_t fc;
94 unsigned int HEADER_LENGTH;
95
96 /* pinfo holds all interresting information for us */
97 struct packetinfo pinfo;
98 struct packetinfo *pinfoptr;
99
100 /* wl_network_t will finally be set and send to the ui */
101 wl_network_t wl_net;
102
103 pinfoptr=&pinfo;
104
105 pinfoptr->isvalid = 0;
106 pinfoptr->pktlen = pkthdr->len;
107
108 if (caplen < IEEE802_11_FC_LEN)
109 {
110 /* This is a garbage packet, because is does not long enough
111 to hold a 802.11b header */
112 pinfoptr->isvalid = 0;
113 return;
114 }
115
116 /* Gets the framecontrol bits (2bytes long) */
117 fc = EXTRACT_LE_16BITS(packet);
118
119 HEADER_LENGTH = GetHeaderLength(fc);
120
121 if (caplen < HEADER_LENGTH)
122 {
123 /* This is a garbage packet, because it is not long enough
124 to hold a correct header of its type */
125 pinfoptr->isvalid = 0;
126 return;
127 }
128
129 /* Decode 802.11b header out of the packet */
130 if (decode_80211b_hdr(packet,pinfoptr) == 0)
131 {
132 /* Justification of the ofset to further process the packet */
133 length -= HEADER_LENGTH;
134 caplen -= HEADER_LENGTH;
135 packet += HEADER_LENGTH;
136 }
137 else /* Something is wrong,could not be a correct packet */
138 return;
139
140 switch (FC_TYPE(fc))
141 {
142 /* Is it a managemnet frame? */
143 case T_MGMT:
144 switch (FC_SUBTYPE(fc))
145 {
146 case ST_BEACON:
147 if (handle_beacon(fc, packet,pinfoptr) ==0)
148 {
149 if (!strcmp(pinfoptr->desthwaddr,"ff:ff:ff:ff:ff:ff") == 0)
150 {
151 /* Every beacon must have the broadcast as destination
152 so it must be a shitti packet */
153 pinfoptr->isvalid = 0;
154 return;
155 }
156
157 if (pinfoptr->cap_ESS == pinfoptr->cap_IBSS)
158 {
159 /* Only one of both are possible, so must be
160 a noise packet, if this comes up */
161 pinfoptr->isvalid = 0;
162 return;
163 }
164 if (pinfoptr->channel < 1 || pinfoptr->channel > 14)
165 {
166 /* Only channels between 1 and 14 are possible
167 others must be noise packets */
168 pinfoptr->isvalid = 0;
169 return;
170 }
171
172 /* Here should be the infos to the gui issued */
173 if (pinfoptr->cap_ESS == 1 && pinfoptr->cap_IBSS ==0)
174 {
175 wl_loginfo("Found an access point");
176 wl_net.net_type=1;
177 }
178 else if(pinfoptr->cap_ESS == 0 && pinfoptr->cap_IBSS == 2)
179 {
180 wl_loginfo("Found an ad-hoc network");
181 wl_net.net_type=2;
182 }
183
184 if (strcmp (pinfoptr->ssid,NONBROADCASTING) ==0)
185 wl_loginfo("Net is a non-broadcasting network");
186 else
187 wl_loginfo("SSID is: %s", pinfoptr->ssid);
188
189 wl_loginfo("SSID is: %s", pinfoptr->ssid);
190 memset(wl_net.bssid, 0, sizeof(wl_net.bssid));
191 memcpy(wl_net.bssid, pinfoptr->ssid, sizeof(wl_net.bssid)-1);
192
193 wl_loginfo("SSID length is: %d", pinfoptr->ssid_len);
194 wl_net.ssid_len=pinfoptr->ssid_len;
195
196 wl_loginfo("Channel is: %d", pinfoptr->channel);
197 wl_net.channel=pinfoptr->channel;
198 wl_net.wep=pinfoptr->cap_WEP;
199
200 wl_loginfo("Mac is: %s", pinfoptr->sndhwaddr);
201 memset(wl_net.mac, 0, sizeof(wl_net.mac));
202 memcpy(wl_net.mac, pinfoptr->sndhwaddr, sizeof(wl_net.mac)-1);
203
204 if(!send_network_found((char *)guihost, guiport, &wl_net))
205 {
206 wl_logerr("Error sending data to UI: %s", strerror(errno));
207 break;
208 }
209 wl_loginfo("Sent network to GUI '%s:%d'", guihost, guiport);
210 }
211 break;
212
213 default:
214 wl_logerr("Unknown IEEE802.11 frame subtype (%d)", FC_SUBTYPE(fc));
215 break;
216 } /* End of switch over different mgt frame types */
217
218 break;
219
220 case T_CTRL:
221 wl_loginfo("Received control frame, not implemented yet");
222 break;
223
224 case T_DATA:
225 wl_loginfo("Received date frame, not implemented yet");
226 break;
227
228 default:
229 wl_logerr("Unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
230 break;
231 }
232}
233
234/* This decodes the 802.11b frame header out of the 802.11b packet
235 all the infos is placed into the packetinfo structure */
236int decode_80211b_hdr(const u_char *p,struct packetinfo *ppinfo)
237{
238 const struct mgmt_header_t *mgthdr = (const struct mgmt_header_t *) p;
239 ppinfo->fcsubtype = FC_SUBTYPE(mgthdr->fc);
240
241 /* Get the sender, bssid and dest mac address */
242 etheraddr_string(mgthdr->bssid,ppinfo->bssid);
243 etheraddr_string(mgthdr->da,ppinfo->desthwaddr);
244 etheraddr_string(mgthdr->sa,ppinfo->sndhwaddr);
245 ppinfo->fc_wep = FC_WEP(mgthdr->fc);
246 return 0;
247}
248
249
250void etheraddr_string(register const u_char *ep, char *text)
251{
252 static char hex[] = "0123456789abcdef";
253 register unsigned int i, j;
254 register char *cp;
255 char buf[sizeof("00:00:00:00:00:00\0")];
256 cp = buf;
257 if ((j = *ep >> 4) != 0)
258 {
259 *cp++ = hex[j];
260 }
261 else
262 {
263 *cp++ = '0';
264 }
265 *cp++ = hex[*ep++ & 0xf];
266
267 for (i = 5; (int)--i >= 0;)
268 {
269 *cp++ = ':';
270 if ((j = *ep >> 4) != 0)
271 {
272 *cp++ = hex[j];
273 }
274 else
275 {
276 *cp++ = '0';
277 }
278
279 *cp++ = hex[*ep++ & 0xf];
280 }
281 *cp = '\0';
282 strcpy(text,buf);
283}
284
285/* beacon handler */
286int handle_beacon(u_int16_t fc, const u_char *p,struct packetinfo *ppinfo)
287{
288 struct mgmt_body_t pbody;
289 int offset = 0;
290
291 /* Get the static informations out of the packet */
292 memset(&pbody, 0, sizeof(pbody));
293 memcpy(&pbody.timestamp, p, 8);
294 offset += 8;
295 pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
296 offset += 2;
297 pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
298 offset += 2;
299
300 /* Gets the different flags out of the capabilities */
301 ppinfo->cap_ESS = CAPABILITY_ESS(pbody.capability_info);
302 ppinfo->cap_IBSS = CAPABILITY_IBSS(pbody.capability_info);
303 ppinfo->cap_WEP = CAPABILITY_PRIVACY(pbody.capability_info);
304
305 /* Gets the tagged elements out of the packets */
306 while (offset + 1 < ppinfo->pktlen)
307 {
308 switch (*(p + offset))
309 {
310 case E_SSID:
311 memcpy(&(pbody.ssid),p+offset,2); offset += 2;
312 if (pbody.ssid.length > 0)
313 {
314 memcpy(&(pbody.ssid.ssid),p+offset,pbody.ssid.length);
315 offset += pbody.ssid.length;
316 pbody.ssid.ssid[pbody.ssid.length]='\0';
317 if (strcmp((char *)pbody.ssid.ssid,"")==0)
318 memcpy(ppinfo->ssid, NONBROADCASTING, sizeof(ppinfo->ssid));
319 else
320 memcpy(ppinfo->ssid, pbody.ssid.ssid, sizeof(ppinfo->ssid));
321 ppinfo->ssid_len = pbody.ssid.length;
322 }
323 break;
324
325 case E_CHALLENGE:
326 memcpy(&(pbody.challenge),p+offset,2); offset += 2;
327 if (pbody.challenge.length > 0)
328 {
329 memcpy(&(pbody.challenge.text),p+offset,pbody.challenge.length);
330 offset += pbody.challenge.length;
331 pbody.challenge.text[pbody.challenge.length]='\0';
332 }
333 break;
334 case E_RATES:
335 memcpy(&(pbody.rates),p+offset,2); offset += 2;
336 if (pbody.rates.length > 0)
337 {
338 memcpy(&(pbody.rates.rate),p+offset,pbody.rates.length);
339 offset += pbody.rates.length;
340 }
341 break;
342 case E_DS:
343 memcpy(&(pbody.ds),p+offset,3);
344 offset +=3;
345 ppinfo->channel = pbody.ds.channel;
346 break;
347 case E_CF:
348 memcpy(&(pbody.cf),p+offset,8);
349 offset +=8;
350 break;
351 case E_TIM:
352 memcpy(&(pbody.tim),p+offset,2);
353 offset +=2;
354 memcpy(&(pbody.tim.count),p+offset,3);
355 offset +=3;
356 if ((pbody.tim.length -3) > 0)
357 {
358 memcpy((pbody.tim.bitmap),p+(pbody.tim.length -3),(pbody.tim.length -3));
359 offset += pbody.tim.length -3;
360 }
361 break;
362 default:
363
364 offset+= *(p+offset+1) + 2;
365 break;
366 } /* end of switch*/
367 } /* end of for loop */
368 return 0;
369
370} /* End of handle_beacon */
371
372
373int GetHeaderLength(u_int16_t fc)
374{
375 int iLength=0;
376
377 switch (FC_TYPE(fc))
378 {
379 case T_MGMT:
380 iLength = MGMT_HEADER_LEN;
381 break;
382 case T_CTRL:
383 switch (FC_SUBTYPE(fc))
384 {
385 case CTRL_PS_POLL:
386 iLength = CTRL_PS_POLL_LEN;
387 break;
388 case CTRL_RTS:
389 iLength = CTRL_RTS_LEN;
390 break;
391 case CTRL_CTS:
392 iLength = CTRL_CTS_LEN;
393 break;
394 case CTRL_ACK:
395 iLength = CTRL_ACK_LEN;
396 break;
397 case CTRL_CF_END:
398 iLength = CTRL_END_LEN;
399 break;
400 case CTRL_END_ACK:
401 iLength = CTRL_END_ACK_LEN;
402 break;
403 default:
404 iLength = 0;
405 break;
406 }
407 break;
408 case T_DATA:
409 if (FC_TO_DS(fc) && FC_FROM_DS(fc))
410 iLength = 30;
411 else
412 iLength = 24;
413 break;
414 default:
415 wl_logerr("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
416 break;
417 }
418 return iLength;
419}