2 * common.c from Access Point SNMP Utils for Linux
4 * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
5 * Copyright (c) 2005 Jan Rafaj <jr-aputils at cedric dot unob dot cz>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License Version 2 from
9 * June 1991 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <sys/types.h>
28 #include <sys/ioctl.h>
29 #include <sys/socket.h>
32 #define APIP _("Access Point IP-address: ")
33 #define APPASS _("Password (community): ")
34 #define AUTODETECT _("Autodetect AP MIB properties? ")
35 #define APTYPE _("AP MIB type: ")
36 #define APVENDOREXT _("AP MIB vendor extensions: ")
37 #define WANT_SYS_APLABEL _("Do you want to use AP's name as its label? ")
38 #define APLABEL _("Access Point label: ")
39 #define SAVESETTINGS _("Save connect-settings: ")
40 #define POLL_I _("[P] Polling mode interval (tenths of second): ")
41 #define POLL_HELP _("P - change polling mode interval; Q - quit to menu")
49 char *ap_vendorexts[][3] = {
50 { "NONE", "SBRIDGES" }, /* ATMEL410 exts */
51 { "NONE" }, /* NWN exts */
52 { "NONE", "GEMTEK", "EZYNET" }, /* ATMEL12350 exts */
53 { 0 } /* do not delete! */
56 rdprops regdom_types[] = {
57 { 0x10, "FCC (USA)", 1, 11 },
58 { 0x20, "DOC (Canada)", 1, 11 },
59 { 0x30, "ETSI (Europe)", 1, 13 },
60 { 0x31, "Spain", 10, 2 },
61 { 0x32, "France", 10, 4 },
62 { 0x40, "MKK (Japan)", 14, 1 },
63 { 0x41, "MKK1 (Japan)", 1, 14 },
64 { 0x42, "Israel", 3, 7 },
65 { 0x00, "unknown", 1, 14 } /* hopefully 0x00 is not taken by any? */
69 "01", "02", "03", "04", "05", "06", "07",
70 "08", "09", "10", "11", "12", "13", "14"
73 extern WINDOW *main_sub;
74 extern char *community, *prog_title;
75 extern struct in_addr ap_ip;
77 short ap_type, ap_vendorext;
82 int nrow = 14, ncol = 47, brow = (LINES - 5 - nrow) / 2, bcol =
83 (COLS - MCOLS - 2 - ncol) / 2, i;
89 print_top(NULL, _("About"));
92 mvwaddch(main_sub, brow, bcol, ACS_ULCORNER);
93 mvwaddch(main_sub, brow, bcol + ncol, ACS_URCORNER);
94 mvwaddch(main_sub, brow + nrow, bcol, ACS_LLCORNER);
95 mvwaddch(main_sub, brow + nrow, bcol + ncol, ACS_LRCORNER);
96 for (i = 1; i < ncol; i++) {
97 mvwaddch(main_sub, brow, bcol + i, ACS_HLINE);
98 mvwaddch(main_sub, brow + nrow, bcol + i, ACS_HLINE);
100 for (i = 1; i < nrow; i++) {
101 mvwaddch(main_sub, brow + i, bcol, ACS_VLINE);
102 mvwaddch(main_sub, brow + i, bcol + ncol, ACS_VLINE);
105 mvwaddstr(main_sub, brow + 1, bcol + 2, prog_title);
106 sprintf(message, _("From %s"), TITLE);
107 mvwaddstr(main_sub, brow + 2, bcol + 2, message);
108 sprintf(message, _("Version %s"), VERSION);
109 mvwaddstr(main_sub, brow + 3, bcol + 2, message);
110 mvwaddstr(main_sub, brow + 5, bcol + 2,
111 _("Written by Roman Festchook roma@polesye.net"));
112 mvwaddstr(main_sub, brow + 6, bcol + 2,
113 _("and Jan Rafaj jr-aputils@cedric.unob.cz"));
114 mvwaddstr(main_sub, brow + 7, bcol + 2,
115 _("Copyright (c) 2001-2005"));
116 mvwaddstr(main_sub, brow + 8, bcol + 2,
117 _("Roman Festchook and Jan Rafaj"));
118 mvwaddstr(main_sub, brow + 9, bcol + 2, "http://ap-utils.polesye.net/");
119 mvwaddstr(main_sub, brow + 11, bcol + 2,
120 _("This program is distributed under the terms"));
121 mvwaddstr(main_sub, brow +12, bcol + 2,
122 _("of the GNU General Public License version 2."));
123 mvwaddstr(main_sub, brow + 13, bcol + 2,
124 _("See the included COPYING file for details."));
131 print_top(NULL, NULL);
136 void connect_options(unsigned long int ip, int type)
139 * operAccessPointName OIDs used to retrieve AP NAME [in order of
140 * corresponding AP MIB types: ATMEL410, NWN, ATMEL12350]
142 char operAccessPointName[3][12] = {
143 {0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x0A, 0x00},
144 {0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x05, 0x00},
145 {0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x01, 0x0A, 0x00}
148 extern int atmel410_filter; /* boolean; = 1 if we call from ap-gl utility */
149 unsigned char message[256];
150 unsigned char label[17];
153 char save_settings=1;
156 if (reopen_sockfd() == -1) {
157 print_helperr(ERR_SOCKET);
165 print_top(NULL, _("Connect options"));
168 mvwaddstr(main_sub, 1, 1, APIP);
171 mvwaddstr(main_sub, 1, 1 + strlen(APIP), inet_ntoa(ap_ip));
173 print_help(_("Enter IP address of your Access Point."));
174 get_ip(&ap_ip, 1, 1 + strlen(APIP), NULL);
177 mvwaddstr(main_sub, 2, 1, APPASS);
182 print_help(_("Entered characters will not be displayed "
183 "for security reason."));
184 get_pass(message, 2, 1 + strlen(APPASS), 16);
187 i = strlen(message) + 1;
188 community = (char *) malloc(i);
189 strncpy(community, message, i);
191 if (type && !atmel410_filter) {
192 /* entered from ap_search() */
194 /* community already exists */
195 /* wattrset(main_sub, A_BOLD);
196 for(i = 0; community[i++]; waddch(main_sub, '*'));
197 wattrset(main_sub, A_NORMAL);
201 print_menusel(3, 1, APTYPE, ap_types[ap_type]);
203 /* well, we already know the MIB type, but lets find out MIB ext */
206 /* marks that we want offer AP name -> AP label later */
209 mvwaddstr(main_sub, 4, 1, APVENDOREXT);
211 if (atmel410_filter) {
213 print_menusel(3, 1, APTYPE, ap_types[ap_type]);
214 ap_vendorext = NONE; /* no need to choose here, really */
215 /* marks that we want offer AP name -> AP label later */
217 mvwaddstr(main_sub, 4, 1, APVENDOREXT);
219 mvwaddstr(main_sub, 3, 1, AUTODETECT);
221 i = yes_no(3, 1 + strlen(AUTODETECT));
222 clear_main_new(3, 4);
223 mvwaddstr(main_sub, 3, 1, APTYPE);
224 if (i == 2) { /* NO */
226 ap_type = menu_choose(3, 1 + strlen(APTYPE), ap_types, 3);
227 print_bold(main_sub, ap_types[ap_type]);
228 mvwaddstr(main_sub, 4, 1, APVENDOREXT);
230 for (i = 0; ap_vendorexts[ap_type][i]; i++);
232 ap_vendorext = NONE; /* no need to choose here, really */
234 ap_vendorext = menu_choose(4, 1 + strlen(APVENDOREXT),
235 ap_vendorexts[ap_type], i);
237 if (get_mib_details() == -1) {
238 clear_main_new(1, 4);
241 print_bold(main_sub, ap_types[ap_type]);
242 mvwaddstr(main_sub, 4, 1, APVENDOREXT);
246 print_bold(main_sub, ap_vendorexts[ap_type][ap_vendorext]);
249 _("This label will be stored on HDD (independently on AP name!)."));
252 * (being called from ap_search()) or (YES for AP type autodetection)
253 * => offer possibility to use AP's name as the label
255 mvwaddstr(main_sub, 5, 1, WANT_SYS_APLABEL);
257 if (yes_no(5, 1 + strlen(WANT_SYS_APLABEL)) == 1) { /* YES */
258 varbinds[0].oid = operAccessPointName[ap_type];
259 varbinds[0].len_oid = (ap_type == NWN ?
260 8 : sizeof(operAccessPointName[ap_type]));
261 varbinds[0].type = NULL_VALUE;
262 varbinds[0].len_val = 0;
264 print_help(WAIT_RET);
265 if (snmp(varbinds, i, GET) <= 0) {
266 print_helperr(ERR_RET);
269 clear_main_new(5, 6);
270 mvwaddstr(main_sub, 5, 1, APLABEL);
271 wattrset(main_sub, A_BOLD);
272 for (i = 0; i < varbinds[0].len_val && i < 16 &&
273 *(varbinds[0].value + i); i++) {
274 label[i] = *(varbinds[0].value + i);
275 waddch(main_sub, label[i]);
278 wattrset(main_sub, A_NORMAL);
279 if (strlen(varbinds[0].value) > 16) {
280 print_helperr("Warning! AP LABEL truncated to first 16 characters of AP NAME. Press any key.");
289 if (i != -1) { /* we have NOT been asked with WANT_SYS_APLABEL */
290 clear_main_new(5, 6);
291 mvwaddstr(main_sub, 5, 1, APLABEL);
292 get_value(message, 5, 1 + strlen(APLABEL), -sizeof(label), ANY_STRING,
294 strncpy(label, message, strlen(message) + 1);
297 mvwaddstr(main_sub, 6, 1, SAVESETTINGS);
299 save_settings = on_off(6, 1 + strlen(SAVESETTINGS));
300 clear_main_new(6, 7);
301 print_menusel(6, 1, SAVESETTINGS, (save_settings == 1) ? ON : OFF);
303 print_bottom(inet_ntoa(ap_ip));
305 if(save_settings == 1) {
306 if ((home_dir = getenv("HOME"))) {
307 sprintf(message, "%s/.ap-config", home_dir);
308 if ((fd = open(message, O_CREAT|O_WRONLY|O_APPEND, 0600)) != -1) {
309 sprintf(message, "%s:%s:%s:%d:%d\n", inet_ntoa(ap_ip),
310 community, label, ap_type, ap_vendorext);
311 write(fd, message, strlen(message));
313 wbkgd(main_sub, A_NORMAL);
315 print_help(DONE_WRITING_APCONF);
317 print_helperr(ERR_WRITING_APCONF);
324 print_top(NULL, NULL);
330 * Determines AP MIB type (fills ap_type global), and AP MIB vendor extensions
331 * (fills ap_vendorext global). Returns with -1 on error or 0
332 * if everything is OK.
334 int get_mib_details()
336 char sysDescr_NWN[] = {
337 0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00
339 char sysDescr_ATMEL[] = {
340 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x01, 0x00
343 * ATMEL410: SMARTBRIDGES MIB define this with length 4 (IpAddress); others
344 * (hopefully) do not define this but eventually return (hopefully)
345 * different value than 4.
347 char AuthRadiusIP_ATMEL[] = {
348 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x03, 0x00
350 /* ATMEL12350: GEMTEK and EZYNET MIBs define length 160, others 92 or 128 */
351 char sysDeviceInfo_ATMEL[] = {
352 0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x01, 0x01, 0x05, 0x00
354 /* ATMEL12350: EZYNET MIB defines length 104, others 88 */
355 char wirelessStatistics_ATMEL[] = {
356 0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x03, 0x01, 0x00
362 print_help(_("Trying to probe AP for MIB properties. Please wait..."));
364 /* first, determine the private MIB types according to enterprises ID */
365 varbinds[0].oid = sysDescr_NWN;
366 varbinds[0].len_oid = sizeof(sysDescr_NWN);
367 varbinds[0].value = NULL;
368 varbinds[0].len_val = 0;
369 varbinds[0].type = NULL_VALUE;
370 if (snmp(varbinds, 1, GET) > 0) {
373 varbinds[0].oid = sysDescr_ATMEL;
374 varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
375 varbinds[0].value = NULL;
376 varbinds[0].len_val = 0;
377 varbinds[0].type = NULL_VALUE;
378 if (snmp(varbinds, 1, GET) > 0) {
381 sysDescr_ATMEL[5] = 0xE0;
382 sysDescr_ATMEL[6] = 0x3E;
383 varbinds[0].oid = sysDescr_ATMEL;
384 varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
385 varbinds[0].value = NULL;
386 varbinds[0].len_val = 0;
387 varbinds[0].type = NULL_VALUE;
388 if (snmp(varbinds, 1, GET) > 0) {
389 ap_type = ATMEL12350;
391 print_helperr(_("Unable to determine AP MIB properties "
392 "(no response from AP). Press any key."));
400 * It is best to do the following HERE and FOR ONCE ONLY: find out more
401 * about specific MIB vendor extensions - we'll check against them
402 * on different places later.
407 if (ap_type == ATMEL410) {
408 varbinds[0].oid = AuthRadiusIP_ATMEL;
409 varbinds[0].len_oid = sizeof(AuthRadiusIP_ATMEL);
410 varbinds[0].value = NULL;
411 varbinds[0].len_val = 0;
412 varbinds[0].type = NULL_VALUE;
414 i = snmp(varbinds, 1, GET);
416 print_helperr(ERR_RET);
422 * i == 0 => 'no such variable in the MIB' returned =>
423 * consider 'ap_vendorext = NONE' too.
426 if (varbinds[0].len_val == 4)
427 ap_vendorext = SBRIDGES;
430 if (ap_type == ATMEL12350) {
431 varbinds[0].oid = sysDeviceInfo_ATMEL;
432 varbinds[0].len_oid = sizeof(sysDeviceInfo_ATMEL);
433 varbinds[0].value = NULL;
434 varbinds[0].len_val = 0;
435 varbinds[0].type = NULL_VALUE;
436 varbinds[1].oid = wirelessStatistics_ATMEL;
437 varbinds[1].len_oid = sizeof(wirelessStatistics_ATMEL);
438 varbinds[1].value = NULL;
439 varbinds[1].len_val = 0;
440 varbinds[1].type = NULL_VALUE;
442 if (snmp(varbinds, 2, GET) <= 0) {
443 print_helperr(ERR_RET);
448 if (varbinds[0].len_val == 160)
449 ap_vendorext = GEMTEK;
451 if (varbinds[1].len_val == 104)
452 ap_vendorext = EZYNET;
476 * Sets different-than-default (1 sec.) polling interval for polling-active
477 * modes, from interval <0.1;86400> seconds.
478 * poll_delay is natively in tenths of second.
480 void polling_interval()
482 unsigned char message[256];
486 print_help(POLL_HELP);
489 sprintf(message, _("%s%u"), POLL_I, poll_delay);
490 mvwaddstr(main_sub, 0, 0, message);
491 sprintf(message, _("(%0.1f seconds)"), (float) poll_delay / 10);
492 mvwaddstr(main_sub, 1, strlen(POLL_I), message);
498 get_value(message, 0, strlen(POLL_I), 7, INT_STRING, 1, 864000,
500 poll_delay = atoi(message);
501 clear_main_new(0, 2);
516 * Expects regulatory domain code on input and returns index of a corresponding
517 * regdom_types[] member, that describes the given regulatory domain properties.
519 int regdom_idx(char regdom)
523 for (i = 0; ®dom_types[i]; i++)
524 if (regdom_types[i].code == regdom)