2 This file is part of Wi-viz (http://wiviz.natetrue.com).
4 Wi-viz is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License v2 as published by
6 the Free Software Foundation.
8 Wi-viz is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with Wi-viz; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #define HOST_TIMEOUT 300
23 #include "wl_access.h"
25 #include "channelhopper.h"
34 #define nonzeromac(x) memcmp(x, "\0\0\0\0\0\0", 6)
36 void dealWithPacket(wiviz_cfg
* cfg
, struct pcap_pkthdr
* header
, const u_char
* packet
);
37 wiviz_host
* gotHost(wiviz_cfg
* cfg
, u_char
* mac
, host_type type
);
38 void fprint_mac(FILE * outf
, u_char
* mac
, char * extra
);
39 void print_mac(u_char
* mac
, char * extra
);
40 void print_host(FILE * outf
, wiviz_host
* host
);
41 void __cdecl
signal_handler(int);
42 void readWL(wiviz_cfg
* cfg
);
45 wiviz_cfg
* global_cfg
;
47 ////////////////////////////////////////////////////////////////////////////////
48 int main(int argc
, char * * argv
) {
51 char errbuf
[PCAP_ERRBUF_SIZE
];
53 int oldMonitor
, newMonitor
;
54 struct pcap_pkthdr header
;
58 int defaultHopSeq
[] = { 1, 3, 6, 8, 11 };
61 signal(SIGUSR1
, &signal_handler
);
62 signal(SIGUSR2
, &signal_handler
);
64 fprintf(stderr
, "Wi-Viz infogathering daemon by Nathan True\n");
66 memset(&cfg
, 0, sizeof(wiviz_cfg
));
68 cfg
.lastKeepAlive
= time(NULL
);
69 cfg
.channelHopping
= 0;
70 cfg
.channelDwellTime
= 1000;
71 cfg
.channelHopSeqLen
= 5;
72 memcpy(cfg
.channelHopSeq
, defaultHopSeq
, sizeof(defaultHopSeq
));
74 wl_ioctl(WL_DEVICE
, WLC_GET_MAGIC
, &i
, 4);
75 if (i
!= WLC_IOCTL_MAGIC
) {
76 fprintf(stderr
, "Wireless magic not correct, not querying wl for info\n");
81 wl_ioctl(WL_DEVICE
, WLC_GET_MONITOR
, &oldMonitor
, 4);
83 wl_ioctl(WL_DEVICE
, WLC_SET_MONITOR
, &newMonitor
, 4);
90 handle
= pcap_open_live(dev
, BUFSIZ
, 1, 0, errbuf
);
92 dev
= "c:\\cifsroot\\wdump2.pcap";
93 handle
= pcap_open_offline(dev
, errbuf
);
101 fprintf(stderr
, "Failure to open pcap!\nErr=%s\n", errbuf
);
105 packet
= pcap_next(handle
, &header
);
107 dealWithPacket(&cfg
, &header
, packet
);
108 if (time(NULL
) - cfg
.lastKeepAlive
> 30) stop
= 1;
111 signal_handler(SIGUSR1
);
113 if (cfg
.channelHopperPID
) kill(cfg
.channelHopperPID
, SIGKILL
);
115 for (i
= 0; i
< MAX_HOSTS
; i
++) {
116 print_host(stderr
, cfg
.hosts
+ i
);
117 if (cfg
.hosts
[i
].occupied
) printf("\n");
118 if (cfg
.hosts
[i
].apInfo
) free(cfg
.hosts
[i
].apInfo
);
119 if (cfg
.hosts
[i
].staInfo
) free(cfg
.hosts
[i
].staInfo
);
122 wl_ioctl(WL_DEVICE
, WLC_SET_MONITOR
, &oldMonitor
, 4);
128 ////////////////////////////////////////////////////////////////////////////////
129 void writeJavascript() {
134 outf
= fopen("/tmp/wiviz-pipe", "w");
136 fprintf(stderr
, "Failure to open output file\n");
140 global_cfg
->lastKeepAlive
= time(NULL
);
142 if(global_cfg
->readFromWl
) readWL(global_cfg
);
144 fprintf(outf
, "top.hosts = new Array(\n");
145 for (i
= 0; i
< MAX_HOSTS
; i
++) {
146 h
= global_cfg
->hosts
+ i
;
147 if (h
->occupied
== 0) continue;
148 if (time(NULL
) - h
->lastSeen
> HOST_TIMEOUT
) {
151 fprintf(outf
, " new Array(");
153 fprintf(outf
, "),\n");
155 fprintf(outf
, "new Array());\n");
156 fprintf(outf
, "var cfg_string = 'channel-");
157 if (global_cfg
->channelHopping
) {
158 fprintf(outf
, "hopping");
161 fprintf(outf
, "%i", global_cfg
->curChannel
);
163 fprintf(outf
, "';\ntop.wiviz_callback(top.hosts, cfg_string);\n");
167 ////////////////////////////////////////////////////////////////////////////////
168 void reloadConfig() {
170 wiviz_cfg
* cfg
= global_cfg
;
171 char filebuffer
[512];
172 char * fbptr
, * p
, * v
, * vv
;
174 int hopCfgChanged
= 0;
176 int newHopSeqLen
= 0;
178 fprintf(stderr
, "Loading config file\n");
180 cnf
= fopen("/tmp/wiviz-cfg", "r");
182 fprintf(stderr
, "Wiviz: No config file (/tmp/wiviz-cfg) present, using defaults\n");
186 fblen
= fread(filebuffer
, 1, 512, cnf
);
189 fprintf(stderr
, "Error reading config file\n");
192 filebuffer
[fblen
] = 0;
193 fprintf(stderr
, "Read %i bytes from config file\n", fblen
);
197 while (fbptr
< filebuffer
+ fblen
&& *fbptr
!= 0) {
199 //Find end of parameter
200 for (; *fbptr
!= '=' && *fbptr
!= 0; fbptr
++);
204 for (; *fbptr
!= '&' && *fbptr
!= 0; fbptr
++);
206 fprintf(stderr
, "Config: %s=%s\n", p
, v
);
207 //Apply configuration
208 if (!strcmp(p
, "channelsel")) {
210 cfg
->channelHopping
= 0;
211 if (!strcmp(v
, "hop")) {
212 //Set channel hopping
213 cfg
->channelHopping
= 1;
216 else if (!strcmp(v
, "nochange")) {
217 //Don't change anything, read channel from wireless card
222 if (val
< 1 || val
> 14) {
223 fprintf(stderr
, "Channel setting in config file invalid (%i)\n", cfg
->curChannel
);
226 cfg
->curChannel
= val
;
227 if (cfg
->readFromWl
) {
228 if (wl_ioctl(WL_DEVICE
, WLC_SET_CHANNEL
, &cfg
->curChannel
, 4) < 0) {
229 fprintf(stderr
, "Channel set to %i failed\n", cfg
->curChannel
);
233 fprintf(stderr
, "Can't set channel, no Broadcom wireless device present\n");
238 if (!strcmp(p
, "hopdwell")) {
240 if (val
< 100) val
= 100;
241 if (val
> 30000) val
= 30000;
242 if (cfg
->channelDwellTime
!= val
) hopCfgChanged
= 1;
243 cfg
->channelDwellTime
= val
;
245 if (!strcmp(p
, "hopseq")) {
246 cfg
->channelHopSeqLen
= 0;
248 for (vv
= v
; *vv
!= ',' && *vv
!= 0; vv
++);
250 cfg
->channelHopSeq
[cfg
->channelHopSeqLen
++] = atoi(v
);
254 cfg
->channelHopSeq
[cfg
->channelHopSeqLen
++] = atoi(v
);
259 if (!strcmp(p, "")) {
263 //Apply channel hopper settings
264 if (cfg
->channelHopping
== 0 && cfg
->channelHopperPID
) {
265 kill(cfg
->channelHopperPID
, SIGKILL
);
266 cfg
->channelHopperPID
= 0;
268 if (cfg
->channelHopping
== 1 && hopCfgChanged
) {
269 if (cfg
->channelHopperPID
) kill(cfg
->channelHopperPID
, SIGKILL
);
270 if ((cfg
->channelHopperPID
= fork()) == 0) {
276 ////////////////////////////////////////////////////////////////////////////////
277 void __cdecl
signal_handler(int signum
) {
278 if (signum
== SIGUSR1
) writeJavascript();
279 if (signum
== SIGUSR2
) reloadConfig();
282 ////////////////////////////////////////////////////////////////////////////////
283 void dealWithPacket(wiviz_cfg
* cfg
, struct pcap_pkthdr
* header
, const u_char
* packet
) {
284 ieee802_11_hdr
* hWifi
;
287 wiviz_host
* emergebss
;
288 host_type type
= typeUnknown
;
294 ieee_802_11_mgt_frame
* m
;
295 char * src
= "\0\0\0\0\0\0";
296 char * dst
= "\0\0\0\0\0\0";
297 char * bss
= "\0\0\0\0\0\0";
302 ap_enc_type encType
= aetUnknown
;
305 if (header
->len
< sizeof(prism_hdr
) + sizeof(ieee802_11_hdr
)) return;
306 hPrism
= (prism_hdr
*) packet
;
307 hWifi
= (ieee802_11_hdr
*) (packet
+ (hPrism
->msg_length
));
309 //Parse the prism DIDs
310 i
= (prism_did
*)((char *)hPrism
+ sizeof(prism_hdr
));
311 while ((int)i
< (int)hWifi
) {
312 if (i
->did
== pdn_rssi
) rssi
= *(int *)(i
+1);
313 i
= (prism_did
*) ((int)(i
+1) + i
->length
);
316 //Establish the frame type
317 wfType
= ((hWifi
->frame_control
& 0xF0) >> 4) + ((hWifi
->frame_control
& 0xC) << 2);
319 case mgt_assocRequest
:
320 case mgt_reassocRequest
:
321 case mgt_probeRequest
:
326 case mgt_assocResponse
:
327 case mgt_reassocResponse
:
328 case mgt_probeResponse
:
336 to_ds
= hWifi
->flags
& IEEE80211_TO_DS
;
337 from_ds
= hWifi
->flags
& IEEE80211_FROM_DS
;
338 if ((wfType
& 0xF0) == 0x20 && (wfType
& 0xF) < 4) {
342 if (!from_ds
) type
= typeSta
;
344 if (!to_ds
&& !from_ds
) bss
= hWifi
->addr3
;
345 if (to_ds
&& !from_ds
) bss
= hWifi
->addr1
;
346 if (!to_ds
&& from_ds
) bss
= hWifi
->addr2
;
348 if (type
== typeUnknown
) return;
350 //Parse the 802.11 tags
351 if (wfType
== mgt_probeResponse
|| wfType
== mgt_beacon
) {
352 m
= (ieee_802_11_mgt_frame
*) (hWifi
+ 1);
353 if (m
->caps
& MGT_CAPS_IBSS
) {
357 if (m
->caps
& MGT_CAPS_WEP
) encType
= aetEncWEP
;
358 else encType
= aetUnencrypted
;
359 e
= (ieee_802_11_tag
*) ((int) m
+ sizeof(ieee_802_11_mgt_frame
));
360 while ((u_int
)e
< (u_int
)packet
+ header
->len
) {
361 if (e
->tag
== tagSSID
) {
363 ssid
= (char *)(e
+ 1);
365 if (e
->tag
== tagChannel
) {
366 channel
= *(char *)(e
+ 1);
368 if (e
->tag
== tagVendorSpecific
) {
369 if (e
->length
>= 4 && memcmp(e
+ 1, "\x00\x50\xf2\x01", 4) == 0) {
374 e
= (ieee_802_11_tag
*) ((int)(e
+ 1) + e
->length
);
378 //Look up the host in the hash table
379 host
= gotHost(cfg
, src
, type
);
381 //Add any info we received
383 host
->RSSI
= host
->RSSI
* 9 / 10 + (-rssi
* 10);
386 host
->RSSI
= -rssi
* 100;
388 if (type
== typeSta
) {
389 if (nonzeromac(bss
)) {
390 memcpy(host
->staInfo
->connectedBSSID
, bss
, 6);
391 host
->staInfo
->state
= ssAssociated
;
392 emergebss
= gotHost(cfg
, bss
, typeAP
);
393 if (emergebss
->RSSI
== 0) emergebss
->RSSI
= 10000;
394 memcpy(emergebss
->apInfo
->bssid
, bss
, 6);
396 emergebss
->type
= typeAdhocHub
;
397 if (ssidlen
> 0 && ssidlen
<= 32) {
398 memcpy(emergebss
->apInfo
->ssid
, ssid
, ssidlen
);
399 emergebss
->apInfo
->ssidlen
= ssidlen
;
401 if (channel
) emergebss
->apInfo
->channel
= channel
;
402 emergebss
->apInfo
->flags
= hWifi
->flags
;
403 emergebss
->RSSI
= host
->RSSI
;
404 if (encType
!= aetUnknown
) emergebss
->apInfo
->encryption
= encType
;
407 if (wfType
== mgt_probeRequest
&& host
->staInfo
->state
== ssUnknown
) host
->staInfo
->state
= ssUnassociated
;
409 if (type
== typeAP
) {
410 if (nonzeromac(bss
)) {
411 memcpy(host
->apInfo
->bssid
, bss
, 6);
413 if (ssidlen
> 0 && ssidlen
<= 32) {
414 memcpy(host
->apInfo
->ssid
, ssid
, ssidlen
);
415 host
->apInfo
->ssidlen
= ssidlen
;
417 if (channel
) host
->apInfo
->channel
= channel
;
418 host
->apInfo
->flags
= hWifi
->flags
;
419 if (encType
!= aetUnknown
) host
->apInfo
->encryption
= encType
;
423 ////////////////////////////////////////////////////////////////////////////////
424 void print_mac(u_char
* mac
, char * extra
) {
425 fprint_mac(stdout
, mac
, extra
);
428 ////////////////////////////////////////////////////////////////////////////////
429 void fprint_mac(FILE * outf
, u_char
* mac
, char * extra
) {
430 fprintf(outf
, "%02X:%02X:%02X:%02X:%02X:%02X%s",
440 ////////////////////////////////////////////////////////////////////////////////
441 #define MAX_PROBES MAX_HOSTS/2
442 wiviz_host
* gotHost(wiviz_cfg
* cfg
, u_char
* mac
, host_type type
) {
443 int i
= (mac
[5] + (mac
[4] << 8)) % MAX_HOSTS
;
445 wiviz_host
* h
= cfg
->hosts
+ i
;
446 while (h
->occupied
&& memcmp(h
->mac
, mac
, 6)) {
448 if (i
>= MAX_HOSTS
) {
452 if (c
> MAX_PROBES
) break;
455 fprintf(stderr
, "New host, ");
456 fprint_mac(stderr
, mac
, ", type=");
457 fprintf(stderr
, "%s\n", (type
==typeAP
) ? "AP" : ((type
==typeSta
) ? "Sta" : "Unk"));
460 h
->lastSeen
= time(NULL
);
462 memcpy(h
->mac
, mac
, 6);
463 if (h
->type
== typeAP
&& !h
->apInfo
) {
464 h
->apInfo
= (ap_info
*) malloc(sizeof(ap_info
));
465 memset(h
->apInfo
, 0, sizeof(ap_info
));
467 if (h
->type
== typeSta
&& !h
->staInfo
) {
468 h
->staInfo
= (sta_info
*) malloc(sizeof(sta_info
));
469 memset(h
->staInfo
, 0, sizeof(sta_info
));
474 ////////////////////////////////////////////////////////////////////////////////
475 void print_host(FILE * outf
, wiviz_host
* host
) {
478 if (!host
->occupied
) return;
480 fprint_mac(outf
, host
->mac
, "'");
481 fprintf(outf
, ", -%i, '", host
->RSSI
/ 100);
482 switch (host
->type
) {
483 case typeAP
: fprintf(outf
, "ap"); break;
484 case typeSta
: fprintf(outf
, "sta"); break;
485 case typeAdhocHub
: fprintf(outf
, "adhoc"); break;
487 if (host
->type
== typeSta
) {
488 switch(host
->staInfo
->state
) {
490 fprintf(outf
, "-assoc-");
491 fprint_mac(outf
, host
->staInfo
->connectedBSSID
, "");
494 fprintf(outf
, "-unassoc");
497 if (host
->type
== typeAP
|| host
->type
== typeAdhocHub
) {
498 fprintf(outf
, "-channel-%i-ssid-", host
->apInfo
->channel
& 0xFF);
499 for (i
= 0; i
< host
->apInfo
->ssidlen
; i
++) {
500 fprintf(outf
, "\\x%02X", *((char *)host
->apInfo
->ssid
+ i
) & 0xFF);
502 switch (host
->apInfo
->encryption
) {
503 case aetUnknown
: fprintf(outf
, "-?enc-?alg"); break;
504 case aetUnencrypted
: fprintf(outf
, "-unenc-na"); break;
505 case aetEncUnknown
: fprintf(outf
, "-enc-unknown"); break;
506 case aetEncWEP
: fprintf(outf
, "-enc-wep"); break;
507 case aetEncWPA
: fprintf(outf
, "-enc-wpa"); break;
510 fprintf(outf
, "', %i", time(0) - host
->lastSeen
);
513 ////////////////////////////////////////////////////////////////////////////////
514 #define MAX_STA_COUNT 64
515 void readWL(wiviz_cfg
* cfg
) {
517 wiviz_host
* host
, * sta
;
520 channel_info_t channel
;
524 get_mac(WL_DEVICE
, mac
);
526 print_mac(mac
, "\n");
527 if (!nonzeromac(mac
)) return;
528 wl_ioctl(WL_DEVICE
, WLC_GET_AP
, &ap
, 4);
530 host
= gotHost(cfg
, mac
, typeAP
);
531 wl_ioctl(WL_DEVICE
, WLC_GET_BSSID
, host
->apInfo
->bssid
, 6);
532 wl_ioctl(WL_DEVICE
, WLC_GET_SSID
, &ssid
, sizeof(wlc_ssid_t
));
533 memcpy(host
->apInfo
->ssid
, ssid
.SSID
, 32);
534 host
->apInfo
->ssidlen
= ssid
.SSID_len
;
536 wl_ioctl(WL_DEVICE
, WLC_GET_CHANNEL
, &channel
, sizeof(channel_info_t
));
537 host
->apInfo
->channel
= channel
.hw_channel
;
538 macs
= (maclist_t
*) malloc(4 + MAX_STA_COUNT
* sizeof(ether_addr_t
));
539 macs
->count
= MAX_STA_COUNT
;
540 if (wl_ioctl(WL_DEVICE
, WLC_GET_ASSOCLIST
, macs
, 4 + MAX_STA_COUNT
* sizeof(ether_addr_t
)) > -1) {
541 for (i
= 0; i
< macs
->count
; i
++) {
542 sta
= gotHost(cfg
, (char *)&macs
->ea
[i
], typeSta
);
543 memcpy(starssi
.mac
, &macs
->ea
[i
], 6);
545 starssi
.zero_ex_forty_one
= 0x41;
546 if (wl_ioctl(WL_DEVICE
, WLC_GET_RSSI
, &starssi
, 12) < 0) printf("rssifail\n");
547 sta
->RSSI
= -starssi
.RSSI
* 100;
548 sta
->staInfo
->state
= ssAssociated
;
549 memcpy(sta
->staInfo
->connectedBSSID
, host
->apInfo
->bssid
, 6);
554 host
= gotHost(cfg
, mac
, typeSta
);
556 if (wl_ioctl(WL_DEVICE
, WLC_GET_BSSID
, &host
->staInfo
->connectedBSSID
, 6) < 0) {
557 host
->staInfo
->state
= ssUnassociated
;
560 host
->staInfo
->state
= ssAssociated
;
563 if (wl_ioctl(WL_DEVICE
, WLC_GET_CHANNEL
, &channel
, sizeof(channel_info_t
)) >= 0) {
564 cfg
->curChannel
= channel
.hw_channel
;
565 fprintf(stderr
, "Current channel is %i\n", cfg
->curChannel
);
This page took 0.07523 seconds and 5 git commands to generate.