2 * common.c from Access Point SNMP Utils for Linux
4 * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
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.
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.
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
24 #include <sys/types.h>
27 #include <sys/ioctl.h>
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: ")
45 char *ap_vendorexts[][3] = {
46 { "NONE", "SBRIDGES" }, /* ATMEL410 exts */
47 { "NONE" }, /* NWN exts */
48 { "NONE", "TELLUS", "VERNET" } /* ATMEL12350 exts */
51 rdprops regdom_types[] = {
52 { 0x10, "FCC (USA)", 1, 11 },
53 { 0x20, "DOC (Canada)", 1, 11 },
54 { 0x30, "ETSI (Europe)", 1, 13 },
55 { 0x31, "Spain", 10, 2 },
56 { 0x32, "France", 10, 4 },
57 { 0x40, "MKK (Japan)", 14, 1 },
58 { 0x41, "MKK1 (Japan)", 1, 14 },
59 { 0x42, "Israel", 3, 7 },
60 { 0x00, "unknown", 1, 14 } /* hopefully 0x00 is not taken by any? */
64 "01", "02", "03", "04", "05", "06", "07",
65 "08", "09", "10", "11", "12", "13", "14"
68 extern WINDOW *main_sub;
69 extern char *community, *prog_title;
70 short ap_type, ap_vendorext;
72 extern struct in_addr ap_ip;
76 int nrow = 14, ncol = 47, brow = (LINES - 5 - nrow) / 2, bcol =
77 (COLS - MCOLS - 2 - ncol) / 2, i;
83 print_top(NULL, _("About"));
86 mvwaddch(main_sub, brow, bcol, ACS_ULCORNER);
87 mvwaddch(main_sub, brow, bcol + ncol, ACS_URCORNER);
88 mvwaddch(main_sub, brow + nrow, bcol, ACS_LLCORNER);
89 mvwaddch(main_sub, brow + nrow, bcol + ncol, ACS_LRCORNER);
90 for (i = 1; i < ncol; i++) {
91 mvwaddch(main_sub, brow, bcol + i, ACS_HLINE);
92 mvwaddch(main_sub, brow + nrow, bcol + i, ACS_HLINE);
94 for (i = 1; i < nrow; i++) {
95 mvwaddch(main_sub, brow + i, bcol, ACS_VLINE);
96 mvwaddch(main_sub, brow + i, bcol + ncol, ACS_VLINE);
99 mvwaddstr(main_sub, brow + 1, bcol + 2, prog_title);
100 sprintf(message, _("From %s"), TITLE);
101 mvwaddstr(main_sub, brow + 2, bcol + 2, message);
102 sprintf(message, _("Version %s"), VERSION);
103 mvwaddstr(main_sub, brow + 3, bcol + 2, message);
104 mvwaddstr(main_sub, brow + 5, bcol + 2,
105 _("Written by Roman Festchook roma@polesye.net"));
106 mvwaddstr(main_sub, brow + 6, bcol + 2,
107 _("Portions by Jan Rafaj aputils@cedric.unob.cz"));
108 mvwaddstr(main_sub, brow + 7, bcol + 2,
109 _("Copyright (c) 2001-2004"));
110 mvwaddstr(main_sub, brow + 8, bcol + 2,
111 _("Roman Festchook and Jan Rafaj"));
112 mvwaddstr(main_sub, brow + 9, bcol + 2, "http://ap-utils.polesye.net/");
113 mvwaddstr(main_sub, brow + 11, bcol + 2,
114 _("This program is distributed under the terms"));
115 mvwaddstr(main_sub, brow +12, bcol + 2,
116 _("of the GNU General Public License version 2."));
117 mvwaddstr(main_sub, brow + 13, bcol + 2,
118 _("See the included COPYING file for details."));
126 print_top(NULL, NULL);
131 void connect_options(unsigned long int ip, int type)
134 * operAccessPointName OIDs used to retrieve AP NAME [in order of
135 * corresponding AP MIB types: ATMEL410, NWN, ATMEL12350]
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}
143 struct sockaddr_in client;
144 extern int atmel410_filter; /* to check is this function called from ap-gl utility */
145 unsigned char message[256];
146 unsigned char label[17];
149 char save_settings=1;
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;
160 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
161 print_helperr(CREATE_SOCKET_ERROR);
166 if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1) {
167 print_helperr(BIND_SOCKET_ERROR);
175 print_top(NULL, _("Connect options"));
178 mvwaddstr(main_sub, 1, 1, APIP);
181 mvwaddstr(main_sub, 1, 1 + strlen(APIP), inet_ntoa(ap_ip));
183 print_help(_("Enter IP address of your Access Point."));
184 get_ip(&ap_ip, 1, 1 + strlen(APIP), NULL);
187 mvwaddstr(main_sub, 2, 1, APPASS);
192 print_help(_("Entered characters will not be displayed "
193 "for security reason."));
194 get_pass(message, 2, 1 + strlen(APPASS), 16);
197 i = strlen(message) + 1;
198 community = (char *) malloc(i);
199 strncpy(community, message, i);
202 if (type && ! atmel410_filter) {
203 /* entered from ap_search() */
205 /* community already exists */
206 /* wattrset(main_sub, A_BOLD);
207 for(i = 0; community[i++]; waddch(main_sub, '*'));
208 wattrset(main_sub, A_NORMAL);
212 print_menusel(3, 1, APTYPE, ap_types[ap_type]);
214 /* well, we already know the MIB type, but lets find out MIB ext */
217 /* marks that we want offer AP name -> AP label later */
220 mvwaddstr(main_sub, 4, 1, APVENDOREXT);
223 if (atmel410_filter) {
225 print_menusel(3, 1, APTYPE, ap_types[ap_type]);
226 ap_vendorext = NONE; /* no need to choose here, really */
227 /* marks that we want offer AP name -> AP label later */
229 mvwaddstr(main_sub, 4, 1, APVENDOREXT);
231 mvwaddstr(main_sub, 3, 1, AUTODETECT);
233 i = yes_no(3, 1 + strlen(AUTODETECT));
234 clear_main_new(3, 4);
235 mvwaddstr(main_sub, 3, 1, APTYPE);
236 if (i == 2) { /* NO */
241 ap_type = menu_choose(3, 1 + strlen(APTYPE), ap_types, 3);
242 print_bold(main_sub, ap_types[ap_type]);
244 mvwaddstr(main_sub, 4, 1, APVENDOREXT);
246 for (i = 0, p = ap_vendorexts[ap_type]; *p++; i++);
248 ap_vendorext = NONE; /* no need to choose here, really */
250 ap_vendorext = menu_choose(4, 1 + strlen(APVENDOREXT),
251 ap_vendorexts[ap_type], i);
253 if (get_mib_details() == -1) {
254 clear_main_new(1, 4);
257 print_bold(main_sub, ap_types[ap_type]);
259 mvwaddstr(main_sub, 4, 1, APVENDOREXT);
263 print_bold(main_sub, ap_vendorexts[ap_type][ap_vendorext]);
266 _("This label will be stored on HDD (independently on AP name!)."));
269 * (being called from ap_search()) or (YES for AP type autodetection)
270 * => offer possibility to use AP's name as the label
272 mvwaddstr(main_sub, 5, 1, WANT_SYS_APLABEL);
274 if (yes_no(5, 1 + strlen(WANT_SYS_APLABEL)) == 1) { /* YES */
275 varbinds[0].oid = operAccessPointName[ap_type];
276 varbinds[0].len_oid = (ap_type == NWN ?
277 8 : sizeof(operAccessPointName[ap_type]));
278 varbinds[0].type = NULL_VALUE;
279 varbinds[0].len_val = 0;
281 print_help(WAIT_RET);
282 if (snmp(varbinds, i, GET) <= 0) {
283 print_helperr(ERR_RET);
286 clear_main_new(5, 6);
287 mvwaddstr(main_sub, 5, 1, APLABEL);
288 wattrset(main_sub, A_BOLD);
289 for (i = 0; i < varbinds[0].len_val && i < 16 &&
290 *(varbinds[0].value + i); i++) {
291 label[i] = *(varbinds[0].value + i);
292 waddch(main_sub, label[i]);
295 wattrset(main_sub, A_NORMAL);
296 if (strlen(varbinds[0].value) > 16) {
297 print_helperr("Warning! AP LABEL truncated to first 16 characters of AP NAME. Press any key.");
306 if (i != -1) { /* we have NOT been asked with WANT_SYS_APLABEL */
307 clear_main_new(5, 6);
308 mvwaddstr(main_sub, 5, 1, APLABEL);
309 get_value(message, 5, 1 + strlen(APLABEL), -sizeof(label), ANY_STRING,
311 strncpy(label, message, strlen(message) + 1);
314 mvwaddstr(main_sub, 6, 1, SAVESETTINGS);
316 save_settings = on_off(6, 1 + strlen(SAVESETTINGS));
318 print_bottom(inet_ntoa(ap_ip));
320 if(save_settings == 1) {
321 if ((home_dir = getenv("HOME"))) {
322 sprintf(message, "%s/.ap-config", home_dir);
323 if ((fd = open(message, O_CREAT|O_WRONLY|O_APPEND, 0600)) != -1) {
324 sprintf(message, "%s:%s:%s:%d:%d\n", inet_ntoa(ap_ip),
325 community, label, ap_type, ap_vendorext);
326 write(fd, message, strlen(message));
333 print_top(NULL, NULL);
339 * Determines AP MIB type (fills ap_type), and AP MIB vendor extensions
340 * (changes values of ap_vendorext global). Returns with -1 on error or 0
341 * if everything is OK.
343 int get_mib_details()
345 char sysDescr_NWN[] = {
346 0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00
348 char sysDescr_ATMEL[] = {
349 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x01, 0x00
351 char operEthernetAddress_ATMEL[] = {
352 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x02, 0x03, 0x00
354 char Wireless_ATMEL[] = {
355 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x03, 0x01, 0x00
358 char oui_sbridges[3] = { 0x00, 0x30, 0x1A };
359 char oui_tellus[3] = { 0x00, 0x04, 0xDB };
361 print_help(_("Trying to probe AP for MIB properties. Please wait..."));
363 /* first, determine the private MIB types according to enterprises ID */
364 varbinds[0].oid = sysDescr_NWN;
365 varbinds[0].len_oid = sizeof(sysDescr_NWN);
366 varbinds[0].value = NULL;
367 varbinds[0].len_val = 0;
368 varbinds[0].type = NULL_VALUE;
369 if (snmp(varbinds, 1, GET) > 0) {
372 varbinds[0].oid = sysDescr_ATMEL;
373 varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
374 varbinds[0].value = NULL;
375 varbinds[0].len_val = 0;
376 varbinds[0].type = NULL_VALUE;
377 if (snmp(varbinds, 1, GET) > 0) {
380 sysDescr_ATMEL[5] = 0xE0;
381 sysDescr_ATMEL[6] = 0x3E;
382 varbinds[0].oid = sysDescr_ATMEL;
383 varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
384 varbinds[0].value = NULL;
385 varbinds[0].len_val = 0;
386 varbinds[0].type = NULL_VALUE;
387 if (snmp(varbinds, 1, GET) > 0) {
388 ap_type = ATMEL12350;
390 print_helperr(_("Unable to determine AP MIB properties "
391 "(no response from AP). Press any key."));
399 * It is best to do the following HERE and FOR ONCE ONLY: find out more
400 * about specific MIB modifications - we'll use them on different places
403 varbinds[0].type = NULL_VALUE;
404 varbinds[0].oid = operEthernetAddress_ATMEL;
405 varbinds[0].len_oid = sizeof(operEthernetAddress_ATMEL);
406 varbinds[0].len_val = 0;
407 varbinds[1].type = NULL_VALUE;
408 varbinds[1].oid = Wireless_ATMEL;
409 varbinds[1].len_oid = sizeof(Wireless_ATMEL);
410 varbinds[1].len_val = 0;
411 if (ap_type == ATMEL12350) {
412 operEthernetAddress_ATMEL[5] = 0xE0;
413 operEthernetAddress_ATMEL[6] = 0x3E;
414 Wireless_ATMEL[5] = 0xE0;
415 Wireless_ATMEL[6] = 0x3E;
417 if (snmp(varbinds, 2, GET) <= 0) {
418 print_helperr(ERR_RET);
424 * Detection of different vendor-modified ATMEL private MIBs.
425 * Note that results here are considered mutually exclusive, although
426 * MIBs *may* share a lot of properties - for example, the condition
427 * for TELLUS is matched also with VERNET firmware, but we want
428 * unambiguous results => exactly one type is to be returned each pass
429 * => the order of these conditions is important.
433 if (ap_type == ATMEL410 && (memcmp(oui_sbridges, varbinds[0].value, 3) ==0))
434 ap_vendorext = SBRIDGES;
436 if (ap_type == ATMEL12350 && (memcmp(oui_tellus, varbinds[0].value, 3) ==0))
437 ap_vendorext = TELLUS;
439 if (ap_type == ATMEL12350 && varbinds[1].len_val == 104)
440 ap_vendorext = VERNET;
461 * Expects regulatory domain code on input and returns index of a corresponding
462 * regdom_types[] member, that describes the given regulatory domain properties.
464 int regdom_idx(char regdom)
468 for (i = 0; ®dom_types[i]; i++)
469 if (regdom_types[i].code == regdom)