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 #include "ap-curses.h"
28 
29 #define STAS _("Associated Stations")
30 
31 #define MAX_LINES LINES-4
32 
33 extern int LINES;
34 extern WINDOW *main_sub;
35 extern short ap_type;
36 
stations()37 void stations()
38 {
39     struct AssociatedSTAsInfo {
40 	unsigned short Num;
41 	unsigned char MacAddress[6];
42     } *mac = NULL, get;
43     char StasNum[] =
44 	{ 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x05, 0x01,
45 	0x00
46     };
47 
48     char StasMac[] =
49 	{ 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x05, 0x02,
50 	0x00
51     };
52 
53     char bridgeOperationalMode[] = {
54 	        0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x04, 0x01, 0x00
55     };
56 
57 
58     struct MacListStat *first = NULL, *curr = NULL;
59     char message[1024];
60     int mac_num, begin, end, total_mac;
61     varbind varbinds[1];
62 
63 
64     if (ap_type == ATMEL12350) {
65 	StasNum[5] = 0xE0;
66 	StasNum[6] = 0x3E;
67 	StasMac[5] = 0xE0;
68 	StasMac[6] = 0x3E;
69         bridgeOperationalMode[5] = 0xE0;
70 	bridgeOperationalMode[6] = 0x3E;
71     }
72 
73     print_title(STAS);
74 
75     varbinds[0].oid = bridgeOperationalMode;
76     varbinds[0].len_oid = sizeof(bridgeOperationalMode);
77     varbinds[0].value = bridgeOperationalMode;
78     varbinds[0].len_val = 0;
79     varbinds[0].type = NULL_VALUE;
80     print_help(WAIT_RET);
81     if (snmp(varbinds, 1, GET) <= 0) {
82 	  print_helperr(ERR_RET);
83 	  goto exit;
84     }
85 
86     if (*(varbinds[0].value) == 3) {
87 	    mvwaddstr(main_sub, 3, 1, _("AP now in AP Client Mode and don't has any associated stations"));
88 	    print_help(ANY_KEY);
89 	    wrefresh(main_sub);
90 	    getch();
91 	    goto exit;
92     }
93 
94 
95 
96     varbinds[0].oid = StasNum;
97     varbinds[0].len_oid = sizeof(StasNum);
98     varbinds[0].value = StasNum;
99     varbinds[0].type = NULL_VALUE;
100     varbinds[0].len_val = 0;
101     print_help(WAIT_RET);
102     if (snmp(varbinds, 1, GET) <= 0) {
103 	print_helperr(ERR_RET);
104 	getch();
105 	goto exit;
106     }
107 
108     total_mac = *(varbinds[0].value);
109     mac_num = 1;
110 
111     sprintf(message, "%s: %d", STAS, total_mac);
112     print_title(message);
113     mvwaddstr(main_sub, 0, 3, _("Id       MAC address"));
114     noecho();
115 
116     while (mac_num <= total_mac) {
117 
118 	varbinds[0].oid = StasMac;
119 	varbinds[0].len_oid = sizeof(StasMac);
120 	varbinds[0].type = INT_VALUE;
121 	get.Num = swap2(mac_num);
122 	varbinds[0].value = (char *) &get;
123 	varbinds[0].len_val = sizeof(get);
124 
125 	if (snmp(varbinds, 1, SET) <= 0) {
126 	    print_helperr(ERR_RET);
127 	    getch();
128 	    goto exit;
129 	}
130 
131 	if (varbinds[0].len_val == 24) {
132 	    if (mac)
133 		free(mac);
134 	    mac =
135 		(struct AssociatedSTAsInfo *) malloc(varbinds[0].len_val);
136 	    memcpy(mac, varbinds[0].value, varbinds[0].len_val);
137 /*	    mac = (struct AssociatedSTAsInfo *) varbinds[0].value;*/
138 	} else {
139 	    print_helperr(_("AssociatedSTAsInfo packet error"));
140 	    goto exit;
141 	}
142 
143 
144 	if (first == NULL) {
145 	    first =
146 		(struct MacListStat *) malloc(sizeof(struct MacListStat));
147 	    curr = first;
148 	} else {
149 	    curr->next =
150 		(struct MacListStat *) malloc(sizeof(struct MacListStat));
151 	    curr = curr->next;
152 	}
153 
154 	memcpy(curr->addr, mac->MacAddress, 6);
155 	curr->next = NULL;
156 	mac_num++;
157     }
158     begin = 1;
159     end = (MAX_LINES < mac_num) ? MAX_LINES : mac_num;
160     scroll_rows(first, begin, end, 1, 0);
161     print_help(_("Arrows - scroll; S - save to file; Q - quit to menu."));
162     while (1) {
163 	switch (getch()) {
164 	case 'S':
165 	case 's':
166 	    save_Stations(first);
167 	    continue;
168 	case KEY_RIGHT:
169 	case KEY_DOWN:
170 	    if (end < mac_num) {
171 		begin++;
172 		end++;
173 		scroll_rows(first, begin, end, 1, 0);
174 	    }
175 	    continue;
176 	case KEY_UP:
177 	case KEY_LEFT:
178 	    if (begin > 1) {
179 		begin--;
180 		end--;
181 		scroll_rows(first, begin, end, 1, 0);
182 	    }
183 	    continue;
184 	case 'Q':
185 	case 'q':
186 	    goto exit;
187 	}
188     }
189 
190   exit:
191     while ((curr = first)) {
192 	first = curr->next;
193 	free(curr);
194     }
195     print_title("");
196     clear_main(0);
197 }
198 
nwn_stations()199 void nwn_stations()
200 {
201     unsigned char Mac[] =
202 	{ 0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x29, 0x03, 0x01, 0x03, 0x01,
203 	0x02, 0x01, 0x02, 0x80, 0x00 };
204 
205     unsigned char Quality[] =
206 	{ 0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x29, 0x03, 0x01, 0x03, 0x01,
207 	0x02, 0x01, 0x03, 0x80, 0x00  };
208     unsigned char Age[] =
209 	{ 0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x29, 0x03, 0x01, 0x03, 0x01,
210 	0x02, 0x01, 0x04, 0x80, 0x00    };
211     unsigned char RSSI[] =
212 	{ 0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x29, 0x03, 0x01, 0x03, 0x01,
213 	0x02, 0x01, 0x05, 0x80, 0x00    };
214 
215     struct MacListStat *first = NULL, *curr = NULL;
216     char null[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, message[1024];
217     int mac_num, begin, end;
218     varbind varbinds[4];
219     unsigned char next_num;
220 
221 
222     mac_num = 0;
223     print_title(_("Associated stations"));
224     mvwaddstr(main_sub, 0, 3,
225 	      _("Id       MAC address     Quality  Age  RSSI"));
226     noecho();
227     print_help(WAIT_RET);
228 
229     varbinds[0].oid = Mac;
230     varbinds[0].len_oid = sizeof(Mac);
231     varbinds[0].len_val = 0;
232     varbinds[0].type = NULL_VALUE;
233     if (snmp(varbinds, 1, GET_NEXT) <= 0) {
234         print_helperr(ERR_RET);
235         goto exit;
236     }
237    next_num = varbinds[0].oid[varbinds[0].len_oid - 1];
238 
239    while (memcmp(varbinds[0].oid, Mac, sizeof(Mac) - 2) == 0) {
240 
241 	Mac[sizeof(Mac) - 1] = next_num;
242 	Quality[sizeof(Mac) - 1] = next_num;
243 	Age[sizeof(Mac) - 1] = next_num;
244 	RSSI[sizeof(Mac) - 1] = next_num;
245 
246 	if(sizeof(Mac) == varbinds[0].len_oid) {
247 		Mac[sizeof(Mac) - 2] = varbinds[0].oid[varbinds[0].len_oid - 2];
248 		Quality[sizeof(Mac) - 2] = varbinds[0].oid[varbinds[0].len_oid - 2];
249 		Age[sizeof(Mac) - 2]  = varbinds[0].oid[varbinds[0].len_oid - 2];
250 		RSSI[sizeof(Mac) - 2] = varbinds[0].oid[varbinds[0].len_oid - 2];
251 	}
252 
253 	varbinds[0].oid = Mac;
254 	varbinds[0].len_oid = sizeof(Mac);
255 	varbinds[0].len_val = 0;
256 	varbinds[0].type = NULL_VALUE;
257 	varbinds[1].oid = Quality;
258 	varbinds[1].len_oid = sizeof(Quality);
259 	varbinds[1].len_val = 0;
260 	varbinds[1].type = NULL_VALUE;
261 	varbinds[2].oid = Age;
262 	varbinds[2].len_oid = sizeof(Age);
263 	varbinds[2].len_val = 0;
264 	varbinds[2].type = NULL_VALUE;
265 	varbinds[3].oid = RSSI;
266 	varbinds[3].len_oid = sizeof(RSSI);
267 	varbinds[3].len_val = 0;
268 	varbinds[3].type = NULL_VALUE;
269 	if (snmp(varbinds, 4, GET) <= 0) {
270 	    print_helperr(ERR_RET);
271 	    getch();
272 	    goto exit;
273 	}
274 
275 
276 	if (memcmp(null, varbinds[0].value, 6)) {
277 	    if (first == NULL) {
278 		first =
279 		    (struct MacListStat *)
280 		    malloc(sizeof(struct MacListStat));
281 		curr = first;
282 	    } else {
283 		curr->next =
284 		    (struct MacListStat *)
285 		    malloc(sizeof(struct MacListStat));
286 		curr = curr->next;
287 	    }
288 		memcpy(curr->addr, varbinds[0].value, 6);
289 		curr->quality = *varbinds[1].value;
290 		curr->idle = *varbinds[2].value;
291 		curr->rssi = *varbinds[3].value;
292 		curr->next = NULL;
293 		mac_num++;
294 	}
295 
296 	varbinds[0].oid = Mac;
297         varbinds[0].len_oid = sizeof(Mac);
298         varbinds[0].len_val = 0;
299         varbinds[0].type = NULL_VALUE;
300         if (snmp(varbinds, 1, GET_NEXT) <= 0) {
301             print_helperr(ERR_RET);
302             goto exit;
303         }
304 	next_num = varbinds[0].oid[varbinds[0].len_oid - 1];
305 
306     }
307    sprintf(message, "%s: %d", _("Associated stations"), mac_num);
308    print_title(message);
309    if(mac_num) {
310     begin = 1;
311     end = (MAX_LINES < mac_num+1) ? MAX_LINES : mac_num+1;
312     scroll_rows(first, begin, end, 1, 1);
313     print_help(_("Arrows - scroll; S - save to file; Q - quit to menu."));
314     while (1) {
315 	switch (getch()) {
316 	case 'S':
317 	case 's':
318 	    save_Stations(first);
319 	    continue;
320 	case KEY_DOWN:
321 	case KEY_RIGHT:
322 	    if (end < mac_num+1) {
323 		begin++;
324 		end++;
325 		scroll_rows(first, begin, end, 1, 1);
326 	    }
327 	    continue;
328 	case KEY_UP:
329 	case KEY_LEFT:
330 	    if (begin > 1) {
331 		begin--;
332 		end--;
333 		scroll_rows(first, begin, end, 1, 1);
334 	    }
335 	    continue;
336 	case 'Q':
337 	case 'q':
338 	    goto exit;
339 	}
340     }
341    }
342 
343    print_help(ANY_KEY);
344    getch();
345 
346   exit:
347     while ((curr = first)) {
348         first = curr->next;
349 	free(curr);
350     }
351 
352     print_title("");
353     clear_main(0);
354 }
355 
356