]> git.decadent.org.uk Git - ap-utils.git/blob - src/stations.c
Imported Upstream version 1.5~pre1
[ap-utils.git] / src / stations.c
1 /*
2  *      stations.c from Access Point SNMP Utils for Linux
3  *
4  * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
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 Version 2 from
8  * June 1991 as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  */
20 #include <sys/wait.h>
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <fcntl.h>
24 #include <signal.h>
25 #include <string.h>
26 #include "ap-utils.h"
27
28 /*
29  * NOTE: SBRIDGES seems to be currently handled by ap-gl =>
30  * no SBRIDGES-related code here (yet)!
31  */
32
33 #define TITLE_AP _("AP link state")
34
35 /* following for any non-VERNET ATMEL* MIB */
36 #define HEADER_STAS \
37         _(" #            MAC                                               ")
38 /* following for VERNET-enhanced ATMEL12350 MIB */
39 #define HEADER_STAS_VERNET \
40         _(" #     MAC       Parent MAC    RSSI  Status MACn      IP        ")
41
42 #define MAX_LINES LINES-4
43
44 extern int LINES;
45 extern WINDOW *main_sub;
46 extern short ap_type, ap_vendorext;
47 extern int sts_viewtype;
48
49 void atmel_stations()
50 {
51     char bridgeOperationalMode[] = {
52         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x04, 0x01, 0x00
53     };
54     char StasNum[] = {
55         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x05, 0x01, 0x00
56     };
57     char StasMac[] = {
58         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x05, 0x02, 0x00
59     };
60
61     struct AssociatedSTAsInfo {
62         unsigned short Num;
63         unsigned char MacAddress[6];
64         /* following ones are specific for enhanced ATMEL 12350 MIB by VERNET */
65         unsigned char Status;
66         unsigned char Port;
67         unsigned char ParentMacAddress[6];
68         unsigned char RSSI;
69         unsigned char IP[4];
70     } *mac = NULL, get;
71
72     struct MacListStat *first = NULL, *curr = NULL;
73     char message[1024];
74     int mac_idx, begin, end, total_mac;
75     varbind varbinds[1];
76
77     if (ap_type == ATMEL12350) {
78         bridgeOperationalMode[5] = 0xE0;
79         bridgeOperationalMode[6] = 0x3E;
80         StasNum[5] = 0xE0;
81         StasNum[6] = 0x3E;
82         StasMac[5] = 0xE0;
83         StasMac[6] = 0x3E;
84     }   
85
86     /* find out in what mode the AP currently is */
87     varbinds[0].oid = bridgeOperationalMode;
88     varbinds[0].len_oid = sizeof(bridgeOperationalMode);
89     varbinds[0].value = bridgeOperationalMode;
90     varbinds[0].len_val = 0;
91     varbinds[0].type = NULL_VALUE;
92     print_help(WAIT_RET);
93     if (snmp(varbinds, 1, GET) <= 0) {
94           print_helperr(ERR_RET);
95           goto exit;
96     }
97
98     /* for AP in AP-Client mode & without VERNET firmware, disable status */
99     if (*(varbinds[0].value) == 3 && ap_vendorext != VERNET) {
100         mvwaddstr(main_sub, 3, 1, _("AP is currently in AP Client Mode => "
101             "no associated STAtions."));
102         print_help(ANY_KEY);
103         wrefresh(main_sub);
104         getch();
105         goto exit;
106     }
107
108     noecho();
109     wattrset(main_sub, COLOR_PAIR(3));
110     if (ap_vendorext == VERNET)
111         mvwaddstr(main_sub, 0, 0, HEADER_STAS_VERNET);
112     else
113         mvwaddstr(main_sub, 0, 0, HEADER_STAS);
114     wattrset(main_sub, A_NORMAL);
115
116 refresh:
117     /* find out how many STAtions is in the list */
118     varbinds[0].oid = StasNum;
119     varbinds[0].len_oid = sizeof(StasNum);
120     varbinds[0].value = StasNum;
121     varbinds[0].type = NULL_VALUE;
122     varbinds[0].len_val = 0;
123
124     print_help(WAIT_RET);
125
126     if (snmp(varbinds, 1, GET) <= 0) {
127         print_helperr(ERR_RET);
128         getch();
129         goto exit;
130     }
131
132     total_mac = *(varbinds[0].value);
133     print_help(WAIT_SET);
134     mac_idx = 1;
135     while (mac_idx <= total_mac) {
136
137         /* tell the AP we want first mac_idx-th MAC */
138         varbinds[0].oid = StasMac;
139         varbinds[0].len_oid = sizeof(StasMac);
140         varbinds[0].type = INT_VALUE;
141         get.Num = swap2(mac_idx);
142         varbinds[0].value = (char *) &get;
143         varbinds[0].len_val = sizeof(get);
144
145         if (snmp(varbinds, 1, SET) <= 0) {
146             print_helperr(ERR_RET);
147             getch();
148             goto exit;
149         }
150
151         if (varbinds[0].len_val == 24) {
152             if (mac)
153                 free(mac);
154             mac =
155                 (struct AssociatedSTAsInfo *) malloc(varbinds[0].len_val);
156             memcpy(mac, varbinds[0].value, varbinds[0].len_val);
157             /* mac = (struct AssociatedSTAsInfo *) varbinds[0].value; */
158         } else {
159             print_helperr(_("AssociatedSTAsInfo packet error"));
160             goto exit;
161         }
162
163         if (first == NULL) {
164             first =
165                 (struct MacListStat *) malloc(sizeof(struct MacListStat));
166             curr = first;
167         } else {
168             curr->next =
169                 (struct MacListStat *) malloc(sizeof(struct MacListStat));
170             curr = curr->next;
171         }
172
173         memcpy(curr->addr, mac->MacAddress, 6);
174
175         if (ap_vendorext == VERNET) {
176             curr->Status = mac->Status;
177             curr->Port = mac->Port;
178             memcpy(curr->ParentMacAddress, mac->ParentMacAddress, 6);
179             curr->rssi = mac->RSSI;
180             memcpy(&(curr->IP.s_addr), mac->IP, 4);
181         }
182
183         curr->next = NULL;
184         mac_idx++;
185     }
186
187     begin = 1;
188     end = (MAX_LINES < mac_idx) ? MAX_LINES : mac_idx;
189
190     sprintf(message, "%s: %d", TITLE_STAS, total_mac);
191     while (1) {
192         if (ap_vendorext == VERNET) {
193             print_top_rssi(message);
194
195             print_help(_("Arrows - scroll; S - save to file; Q - return; "
196                          "T - toggle view; Other - refresh"));
197             scroll_rows(first, begin, end, 1, 3);
198         } else {
199             print_top(NULL, message);
200             print_help(_("Arrows - scroll; S - save to file; Q - return; "
201                          "Other key - refresh"));
202             scroll_rows(first, begin, end, 1, 0);
203         }
204
205         switch (getch()) {
206             case 'S':
207             case 's':
208                 save_Stations(first);
209                 continue;
210             case KEY_RIGHT:
211             case KEY_DOWN:
212                 if (end < mac_idx) {
213                     begin++;
214                     end++;
215                 }
216                 continue;
217             case KEY_UP:
218             case KEY_LEFT:
219                 if (begin > 1) {
220                     begin--;
221                     end--;
222                 }
223                 continue;
224             case 'Q':
225             case 'q':
226                 goto exit;
227             case 'T':
228             case 't':
229                 if (ap_vendorext == VERNET) {
230                     sts_viewtype += 1;
231                     if (sts_viewtype == 3)
232                         sts_viewtype = 0;
233                 }
234                 continue;
235             default:
236                 while ((curr = first)) {
237                     first = curr->next;
238                     free(curr);
239                 }
240                 first = curr = NULL;
241                 goto refresh;
242         }
243     }
244
245 exit:
246     while ((curr = first)) {
247         first = curr->next;
248         free(curr);
249     }
250     print_top(NULL, NULL);
251     clear_main(0);
252 }
253
254 void nwn_stations()
255 {
256     unsigned char Mac[] = {
257         0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x29, 0x03, 0x01, 0x03, 0x01,
258         0x02, 0x01, 0x02, 0x80, 0x00 };
259     unsigned char Quality[] = {
260         0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x29, 0x03, 0x01, 0x03, 0x01,
261         0x02, 0x01, 0x03, 0x80, 0x00 };
262     unsigned char Age[] = {
263         0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x29, 0x03, 0x01, 0x03, 0x01,
264         0x02, 0x01, 0x04, 0x80, 0x00 };
265     unsigned char RSSI[] = {
266         0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x29, 0x03, 0x01, 0x03, 0x01,
267         0x02, 0x01, 0x05, 0x80, 0x00 };
268
269     struct MacListStat *first = NULL, *curr = NULL;
270     char null[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, message[1024];
271     int mac_idx, begin, end;
272     varbind varbinds[4];
273     unsigned char next_num;
274
275
276     mac_idx = 0;
277     print_top(NULL, TITLE_STAS);
278     mvwaddstr(main_sub, 0, 3,
279         _("Id       MAC address     Quality  Age  RSSI"));
280     noecho();
281     print_help(WAIT_RET);
282
283     varbinds[0].oid = Mac;
284     varbinds[0].len_oid = sizeof(Mac);
285     varbinds[0].len_val = 0;
286     varbinds[0].type = NULL_VALUE;
287     if (snmp(varbinds, 1, GET_NEXT) <= 0) {
288         print_helperr(ERR_RET);
289         goto exit;
290     }
291    next_num = varbinds[0].oid[varbinds[0].len_oid - 1];
292
293    while (memcmp(varbinds[0].oid, Mac, sizeof(Mac) - 2) == 0) {
294
295         Mac[sizeof(Mac) - 1] = next_num;
296         Quality[sizeof(Mac) - 1] = next_num;
297         Age[sizeof(Mac) - 1] = next_num;
298         RSSI[sizeof(Mac) - 1] = next_num;
299
300         if(sizeof(Mac) == varbinds[0].len_oid) {
301                 Mac[sizeof(Mac) - 2] = varbinds[0].oid[varbinds[0].len_oid - 2];
302                 Quality[sizeof(Mac) - 2] = varbinds[0].oid[varbinds[0].len_oid - 2];
303                 Age[sizeof(Mac) - 2]  = varbinds[0].oid[varbinds[0].len_oid - 2];
304                 RSSI[sizeof(Mac) - 2] = varbinds[0].oid[varbinds[0].len_oid - 2];
305         }
306
307         varbinds[0].oid = Mac;
308         varbinds[0].len_oid = sizeof(Mac);
309         varbinds[0].len_val = 0;
310         varbinds[0].type = NULL_VALUE;
311         varbinds[1].oid = Quality;
312         varbinds[1].len_oid = sizeof(Quality);
313         varbinds[1].len_val = 0;
314         varbinds[1].type = NULL_VALUE;
315         varbinds[2].oid = Age;
316         varbinds[2].len_oid = sizeof(Age);
317         varbinds[2].len_val = 0;
318         varbinds[2].type = NULL_VALUE;
319         varbinds[3].oid = RSSI;
320         varbinds[3].len_oid = sizeof(RSSI);
321         varbinds[3].len_val = 0;
322         varbinds[3].type = NULL_VALUE;
323         if (snmp(varbinds, 4, GET) <= 0) {
324             print_helperr(ERR_RET);
325             getch();
326             goto exit;
327         }
328
329         if (memcmp(null, varbinds[0].value, 6)) {
330             if (first == NULL) {
331                 first =
332                     (struct MacListStat *)
333                     malloc(sizeof(struct MacListStat));
334                 curr = first;
335             } else {
336                 curr->next =
337                     (struct MacListStat *)
338                     malloc(sizeof(struct MacListStat));
339                 curr = curr->next;
340             } 
341             memcpy(curr->addr, varbinds[0].value, 6);
342             curr->quality = *varbinds[1].value;
343             curr->idle = *varbinds[2].value;
344             curr->rssi = *varbinds[3].value;
345             curr->next = NULL;
346             mac_idx++;
347         }
348
349         varbinds[0].oid = Mac;
350         varbinds[0].len_oid = sizeof(Mac);
351         varbinds[0].len_val = 0;
352         varbinds[0].type = NULL_VALUE;
353         if (snmp(varbinds, 1, GET_NEXT) <= 0) {
354             print_helperr(ERR_RET);
355             goto exit;
356         }
357         next_num = varbinds[0].oid[varbinds[0].len_oid - 1];
358                                                 
359     }
360
361    if(mac_idx) {
362
363     begin = 1;
364     end = (MAX_LINES < mac_idx + 1) ? MAX_LINES : mac_idx + 1;
365
366     while (1) {
367         print_help(_("Arrows - scroll; S - save to file; Q - return; "
368             "T - toggle view; Other - refresh"));
369
370         scroll_rows(first, begin, end, 1, 1);
371
372         sprintf(message, "%s: %d", TITLE_STAS, mac_idx);
373         print_top_rssi(message);
374
375         switch (getch()) {
376         case 'S':
377         case 's':
378             save_Stations(first);
379             continue;
380         case KEY_DOWN:
381         case KEY_RIGHT:
382             if (end < mac_idx+1) {
383                 begin++;
384                 end++;
385             }
386             continue;
387         case KEY_UP:
388         case KEY_LEFT:
389             if (begin > 1) {
390                 begin--;
391                 end--;
392             }
393             continue;
394         case 'Q':
395         case 'q':
396             goto exit;
397         case 'T':
398         case 't':
399             sts_viewtype += 1;
400             if (sts_viewtype == 3)
401                 sts_viewtype = 0;
402
403             continue;
404         }
405     }
406    }
407    
408    print_help(ANY_KEY);
409    getch();
410    
411   exit:
412     while ((curr = first)) {
413         first = curr->next;
414         free(curr);
415     }
416     
417     print_top(NULL, NULL);
418     clear_main(0);
419 }
420