]> git.decadent.org.uk Git - ap-utils.git/blob - lib/common.c
Imported Upstream version 1.5~pre3~a
[ap-utils.git] / lib / common.c
1 /*
2  *      common.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
21 #include <stdlib.h>
22 #include <string.h>
23 #include <menu.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <sys/ioctl.h>
28 #include "ap-utils.h"
29
30 #define APIP _("Access Point IP-address: ")
31 #define APPASS _("Password (community): ")
32 #define AUTODETECT _("Autodetect AP MIB properties? ")
33 #define APTYPE _("AP MIB type: ")
34 #define APVENDOREXT _("AP MIB vendor extensions: ")
35 #define WANT_SYS_APLABEL _("Do you want to use AP's name as its label? ")
36 #define APLABEL _("Access Point label: ")
37 #define SAVESETTINGS _("Save connect-settings: ")
38
39 char *ap_types[] = {
40     "ATMEL410",
41     "NWN",
42     "ATMEL12350"
43 };
44
45 char *ap_vendorexts[][3] = {
46     { "NONE", "SBRIDGES" },             /* ATMEL410 exts */
47     { "NONE" },                         /* NWN exts */
48     { "NONE", "GEMTEK", "EZYNET" },     /* ATMEL12350 exts */
49     { 0 }                               /* do not delete! */
50 };
51
52 rdprops regdom_types[] = {
53     { 0x10, "FCC (USA)", 1, 11 },
54     { 0x20, "DOC (Canada)", 1, 11 },
55     { 0x30, "ETSI (Europe)", 1, 13 },
56     { 0x31, "Spain", 10, 2 },
57     { 0x32, "France", 10, 4 },
58     { 0x40, "MKK (Japan)", 14, 1 },
59     { 0x41, "MKK1 (Japan)", 1, 14 },
60     { 0x42, "Israel", 3, 7 },
61     { 0x00, "unknown", 1, 14 }  /* hopefully 0x00 is not taken by any? */
62 };
63
64 char *channels[] = {
65     "01", "02", "03", "04", "05", "06", "07",
66     "08", "09", "10", "11", "12", "13", "14"
67 };
68
69 extern WINDOW *main_sub;
70 extern char *community, *prog_title;
71 short ap_type, ap_vendorext;
72 extern int sockfd;
73 extern struct in_addr ap_ip;
74
75 void about()
76 {
77     int nrow = 14, ncol = 47, brow = (LINES - 5 - nrow) / 2, bcol =
78         (COLS - MCOLS - 2 - ncol) / 2, i;
79     char message[100];
80
81     noecho();
82     curs_set(0);
83
84     print_top(NULL, _("About"));
85
86     /* drawing the box */
87     mvwaddch(main_sub, brow, bcol, ACS_ULCORNER);
88     mvwaddch(main_sub, brow, bcol + ncol, ACS_URCORNER);
89     mvwaddch(main_sub, brow + nrow, bcol, ACS_LLCORNER);
90     mvwaddch(main_sub, brow + nrow, bcol + ncol, ACS_LRCORNER);
91     for (i = 1; i < ncol; i++) {
92         mvwaddch(main_sub, brow, bcol + i, ACS_HLINE);
93         mvwaddch(main_sub, brow + nrow, bcol + i, ACS_HLINE);
94     }
95     for (i = 1; i < nrow; i++) {
96         mvwaddch(main_sub, brow + i, bcol, ACS_VLINE);
97         mvwaddch(main_sub, brow + i, bcol + ncol, ACS_VLINE);
98     }
99
100     mvwaddstr(main_sub, brow + 1, bcol + 2, prog_title);
101     sprintf(message, _("From %s"), TITLE);
102     mvwaddstr(main_sub, brow + 2, bcol + 2, message);
103     sprintf(message, _("Version %s"), VERSION);
104     mvwaddstr(main_sub, brow + 3, bcol + 2, message);
105     mvwaddstr(main_sub, brow + 5, bcol + 2,
106         _("Written by Roman Festchook roma@polesye.net"));
107     mvwaddstr(main_sub, brow + 6, bcol + 2,
108         _("and Jan Rafaj jr-aputils@cedric.unob.cz"));
109     mvwaddstr(main_sub, brow + 7, bcol + 2,
110         _("Copyright (c) 2001-2005"));
111     mvwaddstr(main_sub, brow + 8, bcol + 2,
112         _("Roman Festchook and Jan Rafaj"));
113     mvwaddstr(main_sub, brow + 9, bcol + 2, "http://ap-utils.polesye.net/");
114     mvwaddstr(main_sub, brow + 11, bcol + 2,
115         _("This program is distributed under the terms"));
116     mvwaddstr(main_sub, brow +12, bcol + 2,
117         _("of the GNU General Public License version 2."));
118     mvwaddstr(main_sub, brow + 13, bcol + 2,
119         _("See the included COPYING file for details."));
120
121     wrefresh(main_sub);
122
123     print_help(ANY_KEY);
124     getch();
125     print_help("");
126     print_top(NULL, NULL);
127     clear_main(0);
128     return;
129 }
130
131 void connect_options(unsigned long int ip, int type)
132 {
133     /*
134      * operAccessPointName OIDs used to retrieve AP NAME [in order of
135      * corresponding AP MIB types: ATMEL410, NWN, ATMEL12350]
136      */
137     char operAccessPointName[3][12] = {
138       {0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x0A, 0x00},
139       {0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x05, 0x00},
140       {0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x01, 0x0A, 0x00}
141     };
142
143     struct sockaddr_in client;
144     extern int atmel410_filter; /* boolean; = 1 if we call from ap-gl utility */
145     unsigned char message[256];
146     unsigned char label[17];
147     int fd, i;
148     char *home_dir;
149     char save_settings=1;
150     varbind varbinds[1];
151
152     memset(&client, 0, sizeof client);
153     client.sin_family = AF_INET;
154     client.sin_port = INADDR_ANY;
155     client.sin_addr.s_addr = INADDR_ANY;
156
157     if (sockfd)
158         close(sockfd);
159
160     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
161         print_helperr(ERR_CREATING_SOCKET);
162         getch();
163         goto exit;
164     }
165
166     if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1) {
167         print_helperr(ERR_BINDING_SOCKET);
168         getch();
169         goto exit;
170     }
171
172     noecho();
173     curs_set(0);
174
175     print_top(NULL, _("Connect options"));
176
177 get_all_again:
178     mvwaddstr(main_sub, 1, 1, APIP);
179     if (ip) {
180         ap_ip.s_addr = ip;
181         mvwaddstr(main_sub, 1, 1 + strlen(APIP), inet_ntoa(ap_ip));
182     } else {
183         print_help(_("Enter IP address of your Access Point."));
184         get_ip(&ap_ip, 1, 1 + strlen(APIP), NULL);
185     }
186
187     mvwaddstr(main_sub, 2, 1, APPASS);
188
189     i = 0;
190     print_help("");
191
192     print_help(_("Entered characters will not be displayed "
193                  "for security reason."));
194     get_pass(message, 2, 1 + strlen(APPASS), 16);
195     if (community)
196         free(community);
197     i = strlen(message) + 1;
198     community = (char *) malloc(i);
199     strncpy(community, message, i);
200
201     if (type && !atmel410_filter) {
202         /* entered from ap_search() */
203
204         /* community already exists */
205 /*      wattrset(main_sub, A_BOLD);
206         for(i = 0; community[i++]; waddch(main_sub, '*'));
207         wattrset(main_sub, A_NORMAL);
208 */
209         ap_type = --type;
210
211         print_menusel(3, 1, APTYPE, ap_types[ap_type]);
212
213         /* well, we already know the MIB type, but lets find out MIB ext */
214         get_mib_details();
215
216         /* marks that we want offer AP name -> AP label later */
217         i = 1;
218
219         mvwaddstr(main_sub, 4, 1, APVENDOREXT);
220     } else {
221         if (atmel410_filter) {
222             ap_type = --type;
223             print_menusel(3, 1, APTYPE, ap_types[ap_type]);
224             ap_vendorext = NONE; /* no need to choose here, really */
225             /* marks that we want offer AP name -> AP label later */
226             i = 1;
227             mvwaddstr(main_sub, 4, 1, APVENDOREXT);
228         } else {
229             mvwaddstr(main_sub, 3, 1, AUTODETECT);
230             wrefresh(main_sub);
231             i = yes_no(3, 1 + strlen(AUTODETECT));
232             clear_main_new(3, 4);
233             mvwaddstr(main_sub, 3, 1, APTYPE);
234             if (i == 2) { /* NO */
235                 wrefresh(main_sub);
236                 ap_type = menu_choose(3, 1 + strlen(APTYPE), ap_types, 3);
237                 print_bold(main_sub, ap_types[ap_type]);
238                 mvwaddstr(main_sub, 4, 1, APVENDOREXT);
239                 wrefresh(main_sub);
240                 for (i = 0; ap_vendorexts[ap_type][i]; i++);
241                 if (i == 1)
242                     ap_vendorext = NONE; /* no need to choose here, really */
243                 else
244                     ap_vendorext = menu_choose(4, 1 + strlen(APVENDOREXT),
245                     ap_vendorexts[ap_type], i);
246             } else { /* YES */
247                 if (get_mib_details() == -1) {
248                     clear_main_new(1, 4);
249                     goto get_all_again;
250                 }
251                 print_bold(main_sub, ap_types[ap_type]);
252                 mvwaddstr(main_sub, 4, 1, APVENDOREXT);
253             }
254         }
255     }
256     print_bold(main_sub, ap_vendorexts[ap_type][ap_vendorext]);
257
258     print_help(
259         _("This label will be stored on HDD (independently on AP name!)."));
260     if (i == 1) {
261         /*
262          * (being called from ap_search()) or (YES for AP type autodetection)
263          * => offer possibility to use AP's name as the label
264          */
265         mvwaddstr(main_sub, 5, 1, WANT_SYS_APLABEL);
266         wrefresh(main_sub);
267         if (yes_no(5, 1 + strlen(WANT_SYS_APLABEL)) == 1) { /* YES */
268             varbinds[0].oid = operAccessPointName[ap_type];
269             varbinds[0].len_oid = (ap_type == NWN ?
270                 8 : sizeof(operAccessPointName[ap_type]));
271             varbinds[0].type = NULL_VALUE;
272             varbinds[0].len_val = 0;
273
274             print_help(WAIT_RET);
275             if (snmp(varbinds, i, GET) <= 0) {
276                 print_helperr(ERR_RET);
277                 getch();
278             } else {
279                 clear_main_new(5, 6);
280                 mvwaddstr(main_sub, 5, 1, APLABEL);
281                 wattrset(main_sub, A_BOLD);
282                 for (i = 0; i < varbinds[0].len_val && i < 16 &&
283                      *(varbinds[0].value + i); i++) {
284                     label[i] = *(varbinds[0].value + i);
285                     waddch(main_sub, label[i]);
286                 }
287                 label[i] = '\0';
288                 wattrset(main_sub, A_NORMAL);
289                 if (strlen(varbinds[0].value) > 16) {
290                     print_helperr("Warning! AP LABEL truncated to first 16 characters of AP NAME. Press any key.");
291                     getch();
292                 }
293             }
294             print_help("");
295             i = -1;
296         }
297     }
298
299     if (i != -1) { /* we have NOT been asked with WANT_SYS_APLABEL */
300         clear_main_new(5, 6);
301         mvwaddstr(main_sub, 5, 1, APLABEL);
302         get_value(message, 5, 1 + strlen(APLABEL), -sizeof(label), ANY_STRING,
303             0, 0, NULL);
304         strncpy(label, message, strlen(message) + 1);
305     }
306
307     mvwaddstr(main_sub, 6, 1, SAVESETTINGS);
308     wrefresh(main_sub);
309     save_settings = on_off(6, 1 + strlen(SAVESETTINGS));
310     clear_main_new(6, 7);
311     print_menusel(6, 1, SAVESETTINGS, (save_settings == 1) ? ON : OFF);
312
313     print_bottom(inet_ntoa(ap_ip));
314
315     if(save_settings == 1) {
316         if ((home_dir = getenv("HOME"))) {
317             sprintf(message, "%s/.ap-config", home_dir);
318             if ((fd = open(message, O_CREAT|O_WRONLY|O_APPEND, 0600)) != -1) {
319                 sprintf(message, "%s:%s:%s:%d:%d\n", inet_ntoa(ap_ip),
320                     community, label, ap_type, ap_vendorext);
321                 write(fd, message, strlen(message));
322                 close(fd);
323                 print_help(DONE_WRITING_APCONF);
324             } else
325                 print_helperr(ERR_WRITING_APCONF);
326
327             getch();
328         }
329     }
330   exit:
331     print_help("");
332     print_top(NULL, NULL);
333     clear_main(0);
334     return;
335 }
336
337 /*
338  * Determines AP MIB type (fills ap_type global), and AP MIB vendor extensions
339  * (fills ap_vendorext global). Returns with -1 on error or 0
340  * if everything is OK.
341  */
342 int get_mib_details()
343 {
344     char sysDescr_NWN[] = {
345         0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00
346     };
347     char sysDescr_ATMEL[] = {
348         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x01, 0x00
349     };
350     /*
351      * ATMEL410: SMARTBRIDGES MIB define this with length 4 (IpAddress); others
352      * (hopefully) do not define this but eventually return (hopefully)
353      * different value than 4.
354      */
355     char AuthRadiusIP_ATMEL[] = {
356         0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x03, 0x00
357     };
358     /* ATMEL12350: GEMTEK and EZYNET MIBs define length 160, others 128 */
359     char sysDeviceInfo_ATMEL[] = {
360         0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x01, 0x01, 0x05, 0x00
361     };
362     /* ATMEL12350: EZYNET MIB defines length 104, others 88 */
363     char wirelessStatistics_ATMEL[] = {
364         0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x03, 0x01, 0x00
365     };
366
367     varbind varbinds[2];
368     int i;
369
370     print_help(_("Trying to probe AP for MIB properties. Please wait..."));
371
372     /* first, determine the private MIB types according to enterprises ID */
373     varbinds[0].oid = sysDescr_NWN;
374     varbinds[0].len_oid = sizeof(sysDescr_NWN);
375     varbinds[0].value = NULL;
376     varbinds[0].len_val = 0;
377     varbinds[0].type = NULL_VALUE;
378     if (snmp(varbinds, 1, GET) > 0) {
379         ap_type = NWN;
380     } else {
381         varbinds[0].oid = sysDescr_ATMEL;
382         varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
383         varbinds[0].value = NULL;
384         varbinds[0].len_val = 0;
385         varbinds[0].type = NULL_VALUE;
386         if (snmp(varbinds, 1, GET) > 0) {
387             ap_type = ATMEL410;
388         } else {
389             sysDescr_ATMEL[5] = 0xE0;
390             sysDescr_ATMEL[6] = 0x3E;
391             varbinds[0].oid = sysDescr_ATMEL;
392             varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
393             varbinds[0].value = NULL;
394             varbinds[0].len_val = 0;
395             varbinds[0].type = NULL_VALUE;
396             if (snmp(varbinds, 1, GET) > 0) {
397                 ap_type = ATMEL12350;
398             } else {
399                 print_helperr(_("Unable to determine AP MIB properties "
400                     "(no response from AP). Press any key."));
401                 getch();
402                 return -1;
403             }
404         }
405     }
406
407     /*
408      * It is best to do the following HERE and FOR ONCE ONLY: find out more
409      * about specific MIB vendor extensions - we'll check against them
410      * on different places later.
411      */
412
413     ap_vendorext = NONE;
414
415     if (ap_type == ATMEL410) {
416         varbinds[0].oid = AuthRadiusIP_ATMEL;
417         varbinds[0].len_oid = sizeof(AuthRadiusIP_ATMEL);
418         varbinds[0].value = NULL;
419         varbinds[0].len_val = 0;
420         varbinds[0].type = NULL_VALUE;
421
422         i = snmp(varbinds, 1, GET);
423         if (i < 0) {
424             print_helperr(ERR_RET);
425             getch();
426             return -1;
427         }
428
429         /*
430          * i == 0 => 'no such variable in the MIB' returned =>
431          * consider 'ap_vendorext = NONE' too.
432          */
433
434         if (varbinds[0].len_val == 4)
435             ap_vendorext = SBRIDGES;
436     }
437
438     if (ap_type == ATMEL12350) {
439         varbinds[0].oid = sysDeviceInfo_ATMEL;
440         varbinds[0].len_oid = sizeof(sysDeviceInfo_ATMEL);
441         varbinds[0].value = NULL;
442         varbinds[0].len_val = 0;
443         varbinds[0].type = NULL_VALUE;
444         varbinds[1].oid = wirelessStatistics_ATMEL;
445         varbinds[1].len_oid = sizeof(wirelessStatistics_ATMEL);
446         varbinds[1].value = NULL;
447         varbinds[1].len_val = 0;
448         varbinds[1].type = NULL_VALUE;
449
450         if (snmp(varbinds, 2, GET) <= 0) {
451             print_helperr(ERR_RET);
452             getch();
453             return -1;
454         }
455
456         if (varbinds[0].len_val == 160)
457             ap_vendorext = GEMTEK;
458
459         if (varbinds[1].len_val == 104)
460             ap_vendorext = EZYNET;
461     }
462
463     return 0;
464 }
465
466 void exit_program()
467 {
468     endwin();
469     exit(0);
470 }
471
472 void exit_shell()
473 {
474     def_prog_mode();
475     endwin();
476     system("sh");
477     curs_set(0);
478     refresh();
479 }
480
481 /*
482  * Expects regulatory domain code on input and returns index of a corresponding
483  * regdom_types[] member, that describes the given regulatory domain properties.
484  */
485 int regdom_idx(char regdom)
486 {
487     int i;
488
489     for (i = 0; &regdom_types[i]; i++)
490         if (regdom_types[i].code == regdom)
491             return i;
492
493     return i;
494 }
495