author | mjm <mjm> | 2002-11-12 22:12:33 (UTC) |
---|---|---|
committer | mjm <mjm> | 2002-11-12 22:12:33 (UTC) |
commit | eaecbed44924ece119c5b41db2828b4554f263d2 (patch) (unidiff) | |
tree | b87dd3d049ea1768b20192f6c674f8684a41282c /noncore/net/wellenreiter/daemon/source/sniffer.cc | |
parent | 15bc80dffd7a4c52985a742cb3a439da42692478 (diff) | |
download | opie-eaecbed44924ece119c5b41db2828b4554f263d2.zip opie-eaecbed44924ece119c5b41db2828b4554f263d2.tar.gz opie-eaecbed44924ece119c5b41db2828b4554f263d2.tar.bz2 |
pre-alpha version, most things does not work yet.
todo: communication protocol with GUI and implementation of sniffer
Diffstat (limited to 'noncore/net/wellenreiter/daemon/source/sniffer.cc') (more/less context) (show whitespace changes)
-rw-r--r-- | noncore/net/wellenreiter/daemon/source/sniffer.cc | 418 |
1 files changed, 418 insertions, 0 deletions
diff --git a/noncore/net/wellenreiter/daemon/source/sniffer.cc b/noncore/net/wellenreiter/daemon/source/sniffer.cc new file mode 100644 index 0000000..c837505 --- a/dev/null +++ b/noncore/net/wellenreiter/daemon/source/sniffer.cc | |||
@@ -0,0 +1,418 @@ | |||
1 | /* | ||
2 | * rfmon mode sniffer | ||
3 | * This works only with cisco wireless cards with an rfmon | ||
4 | * able driver and not with wifi stuff. | ||
5 | * | ||
6 | * $Id$ | ||
7 | */ | ||
8 | |||
9 | #include "config.hh" | ||
10 | #include "sniffer.hh" | ||
11 | #include "ieee802_11.hh" | ||
12 | #include "extract.hh" | ||
13 | |||
14 | int sniffer(void) | ||
15 | { | ||
16 | if(card_into_monitormode (SNIFFER_DEVICE, CARD_TYPE_NG) < 0) | ||
17 | return 0; | ||
18 | start_sniffing (SNIFFER_DEVICE); | ||
19 | |||
20 | return 1; | ||
21 | } | ||
22 | |||
23 | int card_into_monitormode (char *device, int cardtype) | ||
24 | { | ||
25 | |||
26 | int datalink; /* used for getting the pcap datalink type */ | ||
27 | char CiscoRFMON[35] = "/proc/driver/aironet/"; | ||
28 | FILE *CISCO_CONFIG_FILE; | ||
29 | char errbuf[PCAP_ERRBUF_SIZE]; | ||
30 | pcap_t *handle; | ||
31 | |||
32 | /* Checks if we have a device to sniff on */ | ||
33 | if(device == NULL) | ||
34 | { | ||
35 | printf ("Fatal error i did not have any interfaces to sniff on\n"); | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | /* Setting the prmiscous and up flag to the interface */ | ||
40 | if (card_set_promisc_up (device) == 0) | ||
41 | { | ||
42 | printf ("Interface flags correctly set using ifconfig\n"); | ||
43 | } | ||
44 | |||
45 | /* Check the cardtype and executes the commands to go into monitor mode */ | ||
46 | if (cardtype == CARD_TYPE_CISCO) /* I got a cisco card */ | ||
47 | { | ||
48 | /* bring the sniffer into rfmon mode */ | ||
49 | snprintf(CiscoRFMON, sizeof(CiscoRFMON),DEFAULT_PATH, device); | ||
50 | CISCO_CONFIG_FILE = fopen(CiscoRFMON,"w"); | ||
51 | fputs ("Mode: r",CISCO_CONFIG_FILE); | ||
52 | fputs ("Mode: y",CISCO_CONFIG_FILE); | ||
53 | fputs ("XmitPower: 1",CISCO_CONFIG_FILE); | ||
54 | fclose(CISCO_CONFIG_FILE); | ||
55 | } | ||
56 | else if (cardtype == CARD_TYPE_NG) | ||
57 | { | ||
58 | char wlanngcmd[62]; | ||
59 | snprintf(wlanngcmd, sizeof(wlanngcmd),"%s %s lnxreq_wlansniff channel=1 enable=true",WLANCTL_PATH,device); | ||
60 | if (system (wlanngcmd) != 0) | ||
61 | { | ||
62 | printf ("\n Fatal error could not set %s in raw mode, check cardtype\n",device); | ||
63 | return 0; | ||
64 | } | ||
65 | } | ||
66 | else if (cardtype == CARD_TYPE_HOSTAP) | ||
67 | { | ||
68 | printf ("Got a host-ap card, nothing is implemented now\n"); | ||
69 | } | ||
70 | |||
71 | |||
72 | /* Check the interface if it is in the correct raw mode */ | ||
73 | handle = pcap_open_live(device, BUFSIZ, 1, 0, errbuf); | ||
74 | |||
75 | /* getting the datalink type */ | ||
76 | datalink = pcap_datalink(handle); | ||
77 | |||
78 | if (datalink == DLT_IEEE802_11) /* Rawmode is IEEE802_11 */ | ||
79 | { | ||
80 | printf ("Your successfully listen on %s in 802.11 raw mode\n",device); | ||
81 | pcap_close(handle); | ||
82 | return 0; | ||
83 | |||
84 | } | ||
85 | else | ||
86 | { | ||
87 | printf ("Fatal error, cannot continue, your interface %s does not work in the correct 802.11 raw mode, check you driver please\n",device); | ||
88 | pcap_close(handle); | ||
89 | return 0; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | int card_set_promisc_up (char * device) | ||
94 | { | ||
95 | int ret; | ||
96 | char ifconfigcmd[32]; | ||
97 | snprintf(ifconfigcmd,sizeof(ifconfigcmd),SBIN_PATH, device); | ||
98 | ret = system (ifconfigcmd); | ||
99 | if (ret > 0) | ||
100 | { | ||
101 | printf ("\nFatal error, could not execute %s please check your card,binary location and permission\n",ifconfigcmd); | ||
102 | return 0; | ||
103 | } | ||
104 | return 1; | ||
105 | } | ||
106 | |||
107 | int start_sniffing (char * device) | ||
108 | { | ||
109 | |||
110 | pcap_t *handletopcap; | ||
111 | char errbuf[PCAP_ERRBUF_SIZE]; | ||
112 | |||
113 | /* opening the pcap for sniffing */ | ||
114 | handletopcap = pcap_open_live(device, BUFSIZ, 1, 1000, errbuf); | ||
115 | |||
116 | /* Next few lines a taken out of kismet */ | ||
117 | #ifdef HAVE_PCAP_NONBLOCK | ||
118 | pcap_setnonblock(handletopcap, 1, errstr); | ||
119 | #endif | ||
120 | |||
121 | /*start scanning */ | ||
122 | pcap_loop(handletopcap,-1,process_packets,NULL); | ||
123 | |||
124 | printf("\nDone processing packets... wheew!\n"); | ||
125 | return 1; | ||
126 | } | ||
127 | |||
128 | void process_packets(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char* packet) | ||
129 | { | ||
130 | u_int caplen = pkthdr->caplen; | ||
131 | u_int length = pkthdr->len; | ||
132 | u_int16_t fc; | ||
133 | u_int HEADER_LENGTH; | ||
134 | |||
135 | /* pinfo holds all interresting information for us */ | ||
136 | struct packetinfo pinfo; | ||
137 | struct packetinfo *pinfoptr; | ||
138 | pinfoptr=&pinfo; | ||
139 | |||
140 | pinfoptr->isvalid = 0; | ||
141 | pinfoptr->pktlen = pkthdr->len; | ||
142 | if (caplen < IEEE802_11_FC_LEN) | ||
143 | { | ||
144 | /* This is a garbage packet, because is does not long enough | ||
145 | to hold a 802.11b header */ | ||
146 | pinfoptr->isvalid = 0; | ||
147 | return; | ||
148 | } | ||
149 | |||
150 | /* Gets the framecontrol bits (2bytes long) */ | ||
151 | fc = EXTRACT_LE_16BITS(packet); | ||
152 | |||
153 | HEADER_LENGTH = GetHeaderLength(fc); | ||
154 | |||
155 | if (caplen < HEADER_LENGTH) | ||
156 | { | ||
157 | /* This is a garbage packet, because it is not long enough | ||
158 | to hold a correct header of its type */ | ||
159 | pinfoptr->isvalid = 0; | ||
160 | return; | ||
161 | } | ||
162 | |||
163 | /* Decode 802.11b header out of the packet */ | ||
164 | if (decode_80211b_hdr(packet,pinfoptr) == 0) | ||
165 | { | ||
166 | /* Justification of the ofset to further process the packet */ | ||
167 | length -= HEADER_LENGTH; | ||
168 | caplen -= HEADER_LENGTH; | ||
169 | packet += HEADER_LENGTH; | ||
170 | } | ||
171 | else | ||
172 | { /* Something is wrong,could not be a correct packet */ | ||
173 | return; | ||
174 | } | ||
175 | |||
176 | switch (FC_TYPE(fc)) | ||
177 | { | ||
178 | /* Is it a managemnet frame? */ | ||
179 | case T_MGMT: | ||
180 | switch (FC_SUBTYPE(fc)) | ||
181 | { /* Is it a beacon frame? */ | ||
182 | case ST_BEACON: | ||
183 | if (handle_beacon(fc, packet,pinfoptr) ==0) | ||
184 | { | ||
185 | if (!strcmp(pinfoptr->desthwaddr,"ff:ff:ff:ff:ff:ff") == 0) | ||
186 | { | ||
187 | /* Every beacon must have the broadcast as destination | ||
188 | so it must be a shitti packet */ | ||
189 | pinfoptr->isvalid = 0; | ||
190 | return; | ||
191 | } | ||
192 | if (pinfoptr->cap_ESS == pinfoptr->cap_IBSS) | ||
193 | { | ||
194 | /* Only one of both are possible, so must be | ||
195 | a noise packet, if this comes up */ | ||
196 | pinfoptr->isvalid = 0; | ||
197 | return; | ||
198 | } | ||
199 | if (pinfoptr->channel < 1 || pinfoptr->channel > 14) | ||
200 | { | ||
201 | /* Only channels between 1 and 14 are possible | ||
202 | others must be noise packets */ | ||
203 | pinfoptr->isvalid = 0; | ||
204 | return; | ||
205 | } | ||
206 | |||
207 | /* Here should be the infos to the gui issued */ | ||
208 | if (pinfoptr->cap_ESS == 1 &&pinfoptr->cap_IBSS ==0) | ||
209 | { | ||
210 | printf ("\nHave found an accesspoint:"); | ||
211 | } | ||
212 | else if(pinfoptr->cap_ESS == 0 && pinfoptr->cap_IBSS == 1) | ||
213 | { | ||
214 | printf ("\nHave found an AD-HOC station:"); | ||
215 | |||
216 | } | ||
217 | if (strcmp (pinfoptr->ssid,NONBROADCASTING) ==0) | ||
218 | { | ||
219 | printf ("\n\tOn a non-broadcasting network"); | ||
220 | } | ||
221 | else | ||
222 | { | ||
223 | printf ("\n\tOn network : %s",pinfoptr->ssid); | ||
224 | } | ||
225 | printf ("\n\tLen SSID : %d",pinfoptr->ssid_len); | ||
226 | printf ("\n\tOn Channel : %d",pinfoptr->channel); | ||
227 | printf ("\n\tEncryption : %s", pinfoptr->cap_WEP ? "ON" : "OFF"); | ||
228 | printf ("\n\tMacaddress : %s",pinfoptr->sndhwaddr); | ||
229 | printf ("\n\tBssid : %s",pinfoptr->bssid); | ||
230 | printf ("\n\tDest : %s\n",pinfoptr->desthwaddr); | ||
231 | } | ||
232 | break; | ||
233 | default: | ||
234 | printf("Unknown IEEE802.11 frame subtype (%d)",FC_SUBTYPE(fc)); | ||
235 | break; | ||
236 | } /* End of switch over different mgt frame types */ | ||
237 | |||
238 | break; | ||
239 | case T_CTRL: | ||
240 | //decode_control_frames(fc, packet); | ||
241 | printf ("Its a control frame"); | ||
242 | break; | ||
243 | case T_DATA: | ||
244 | //decode_data_frames(fc, packet); | ||
245 | printf ("Its a date frame"); | ||
246 | break; | ||
247 | default: | ||
248 | printf("Unknown IEEE802.11 frame type (%d)",FC_TYPE(fc)); | ||
249 | break; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | |||
254 | /* This decodes the 802.11b frame header out of the 802.11b packet | ||
255 | all the infos is placed into the packetinfo structure */ | ||
256 | int decode_80211b_hdr(const u_char *p,struct packetinfo *ppinfo) | ||
257 | { | ||
258 | const struct mgmt_header_t *mgthdr = (const struct mgmt_header_t *) p; | ||
259 | ppinfo->fcsubtype = FC_SUBTYPE(mgthdr->fc); | ||
260 | |||
261 | /* Get the sender, bssid and dest mac address */ | ||
262 | etheraddr_string(mgthdr->bssid,ppinfo->bssid); | ||
263 | etheraddr_string(mgthdr->da,ppinfo->desthwaddr); | ||
264 | etheraddr_string(mgthdr->sa,ppinfo->sndhwaddr); | ||
265 | ppinfo->fc_wep = FC_WEP(mgthdr->fc); | ||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | |||
270 | void etheraddr_string(register const u_char *ep,char * text) | ||
271 | { | ||
272 | static char hex[] = "0123456789abcdef"; | ||
273 | register u_int i, j; | ||
274 | register char *cp; | ||
275 | char buf[sizeof("00:00:00:00:00:00")]; | ||
276 | cp = buf; | ||
277 | if ((j = *ep >> 4) != 0) | ||
278 | *cp++ = hex[j]; | ||
279 | *cp++ = hex[*ep++ & 0xf]; | ||
280 | for (i = 5; (int)--i >= 0;) { | ||
281 | *cp++ = ':'; | ||
282 | if ((j = *ep >> 4) != 0) | ||
283 | *cp++ = hex[j]; | ||
284 | *cp++ = hex[*ep++ & 0xf]; | ||
285 | } | ||
286 | *cp = '\0'; | ||
287 | strcpy(text,buf); | ||
288 | } | ||
289 | |||
290 | int handle_beacon(u_int16_t fc, const u_char *p,struct packetinfo *ppinfo) | ||
291 | { | ||
292 | struct mgmt_body_t pbody; | ||
293 | int offset = 0; | ||
294 | |||
295 | /* Get the static informations out of the packet */ | ||
296 | memset(&pbody, 0, sizeof(pbody)); | ||
297 | memcpy(&pbody.timestamp, p, 8); | ||
298 | offset += 8; | ||
299 | pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset); | ||
300 | offset += 2; | ||
301 | pbody.capability_info = EXTRACT_LE_16BITS(p+offset); | ||
302 | offset += 2; | ||
303 | |||
304 | /* Gets the different flags out of the capabilities */ | ||
305 | ppinfo->cap_ESS = CAPABILITY_ESS(pbody.capability_info); | ||
306 | ppinfo->cap_IBSS = CAPABILITY_IBSS(pbody.capability_info); | ||
307 | ppinfo->cap_WEP = CAPABILITY_PRIVACY(pbody.capability_info); | ||
308 | |||
309 | /* Gets the tagged elements out of the packets */ | ||
310 | while (offset + 1 < ppinfo->pktlen) | ||
311 | { | ||
312 | switch (*(p + offset)) | ||
313 | { | ||
314 | case E_SSID: | ||
315 | memcpy(&(pbody.ssid),p+offset,2); offset += 2; | ||
316 | if (pbody.ssid.length > 0) | ||
317 | { | ||
318 | memcpy(&(pbody.ssid.ssid),p+offset,pbody.ssid.length); offset += pbody.ssid.length; | ||
319 | pbody.ssid.ssid[pbody.ssid.length]='\0'; | ||
320 | if (strcmp((char *)pbody.ssid.ssid,"")==0) | ||
321 | { | ||
322 | ppinfo->ssid = NONBROADCASTING; | ||
323 | } | ||
324 | else | ||
325 | { | ||
326 | ppinfo->ssid = (char *)pbody.ssid.ssid; | ||
327 | } | ||
328 | ppinfo->ssid_len = pbody.ssid.length; | ||
329 | } | ||
330 | break; | ||
331 | case E_CHALLENGE: | ||
332 | memcpy(&(pbody.challenge),p+offset,2); offset += 2; | ||
333 | if (pbody.challenge.length > 0) | ||
334 | { | ||
335 | memcpy(&(pbody.challenge.text),p+offset,pbody.challenge.length); offset += pbody.challenge.length; | ||
336 | pbody.challenge.text[pbody.challenge.length]='\0'; | ||
337 | } | ||
338 | break; | ||
339 | case E_RATES: | ||
340 | memcpy(&(pbody.rates),p+offset,2); offset += 2; | ||
341 | if (pbody.rates.length > 0) { | ||
342 | memcpy(&(pbody.rates.rate),p+offset,pbody.rates.length); offset += pbody.rates.length; | ||
343 | } | ||
344 | break; | ||
345 | case E_DS: | ||
346 | memcpy(&(pbody.ds),p+offset,3); offset +=3; | ||
347 | ppinfo->channel = pbody.ds.channel; | ||
348 | break; | ||
349 | case E_CF: | ||
350 | memcpy(&(pbody.cf),p+offset,8); offset +=8; | ||
351 | break; | ||
352 | case E_TIM: | ||
353 | memcpy(&(pbody.tim),p+offset,2); offset +=2; | ||
354 | memcpy(&(pbody.tim.count),p+offset,3); offset +=3; | ||
355 | if ((pbody.tim.length -3) > 0) | ||
356 | { | ||
357 | memcpy((pbody.tim.bitmap),p+(pbody.tim.length -3),(pbody.tim.length -3)); | ||
358 | offset += pbody.tim.length -3; | ||
359 | } | ||
360 | break; | ||
361 | default: | ||
362 | |||
363 | offset+= *(p+offset+1) + 2; | ||
364 | break; | ||
365 | } /* end of switch*/ | ||
366 | } /* end of for loop */ | ||
367 | return 1; | ||
368 | |||
369 | } /* End of handle_beacon */ | ||
370 | |||
371 | |||
372 | static int GetHeaderLength(u_int16_t fc) | ||
373 | { | ||
374 | int iLength=0; | ||
375 | |||
376 | switch (FC_TYPE(fc)) { | ||
377 | case T_MGMT: | ||
378 | iLength = MGMT_HEADER_LEN; | ||
379 | break; | ||
380 | case T_CTRL: | ||
381 | switch (FC_SUBTYPE(fc)) { | ||
382 | case CTRL_PS_POLL: | ||
383 | iLength = CTRL_PS_POLL_LEN; | ||
384 | break; | ||
385 | case CTRL_RTS: | ||
386 | iLength = CTRL_RTS_LEN; | ||
387 | break; | ||
388 | case CTRL_CTS: | ||
389 | iLength = CTRL_CTS_LEN; | ||
390 | break; | ||
391 | case CTRL_ACK: | ||
392 | iLength = CTRL_ACK_LEN; | ||
393 | break; | ||
394 | case CTRL_CF_END: | ||
395 | iLength = CTRL_END_LEN; | ||
396 | break; | ||
397 | case CTRL_END_ACK: | ||
398 | iLength = CTRL_END_ACK_LEN; | ||
399 | break; | ||
400 | default: | ||
401 | iLength = 0; | ||
402 | break; | ||
403 | } | ||
404 | break; | ||
405 | case T_DATA: | ||
406 | if (FC_TO_DS(fc) && FC_FROM_DS(fc)) | ||
407 | iLength = 30; | ||
408 | else | ||
409 | iLength = 24; | ||
410 | break; | ||
411 | default: | ||
412 | printf("unknown IEEE802.11 frame type (%d)", | ||
413 | FC_TYPE(fc)); | ||
414 | break; | ||
415 | } | ||
416 | |||
417 | return iLength; | ||
418 | } | ||