X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ap-utils.git;a=blobdiff_plain;f=lib%2Fcommon.c;h=3c1b359157728c03ae62d61beaff76a18a410663;hp=16f342dc00ce196228d3eb64eaee2165efa4355f;hb=30c08d141bacedf0dd15a8eb8e4797fc8c26adeb;hpb=09ed626f25fb3e7c57ad7a59e5261ea005aa498f diff --git a/lib/common.c b/lib/common.c index 16f342d..3c1b359 100644 --- a/lib/common.c +++ b/lib/common.c @@ -2,6 +2,7 @@ * common.c from Access Point SNMP Utils for Linux * * Copyright (c) 2002 Roman Festchook + * Copyright (c) 2005 Jan Rafaj * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 from @@ -25,31 +26,67 @@ #include #include #include +#include #include "ap-utils.h" -#define AUTODETECT _("Autodetect AP type? ") #define APIP _("Access Point IP-address: ") #define APPASS _("Password (community): ") -#define APTYPE _("AP type: ") +#define AUTODETECT _("Autodetect AP MIB properties? ") +#define APTYPE _("AP MIB type: ") +#define APVENDOREXT _("AP MIB vendor extensions: ") +#define WANT_SYS_APLABEL _("Do you want to use AP's name as its label? ") +#define APLABEL _("Access Point label: ") #define SAVESETTINGS _("Save connect-settings: ") +#define POLL_I _("[P] Polling mode interval (tenths of second): ") +#define POLL_HELP _("P - change polling mode interval; Q - quit to menu") + +char *ap_types[] = { + "ATMEL410", + "NWN", + "ATMEL12350" +}; + +char *ap_vendorexts[][3] = { + { "NONE", "SBRIDGES" }, /* ATMEL410 exts */ + { "NONE" }, /* NWN exts */ + { "NONE", "GEMTEK", "EZYNET" }, /* ATMEL12350 exts */ + { 0 } /* do not delete! */ +}; + +rdprops regdom_types[] = { + { 0x10, "FCC (USA)", 1, 11 }, + { 0x20, "DOC (Canada)", 1, 11 }, + { 0x30, "ETSI (Europe)", 1, 13 }, + { 0x31, "Spain", 10, 2 }, + { 0x32, "France", 10, 4 }, + { 0x40, "MKK (Japan)", 14, 1 }, + { 0x41, "MKK1 (Japan)", 1, 14 }, + { 0x42, "Israel", 3, 7 }, + { 0x00, "unknown", 1, 14 } /* hopefully 0x00 is not taken by any? */ +}; + +char *channels[] = { + "01", "02", "03", "04", "05", "06", "07", + "08", "09", "10", "11", "12", "13", "14" +}; extern WINDOW *main_sub; extern char *community, *prog_title; -extern short ap_type; -extern int sockfd; extern struct in_addr ap_ip; -extern char *ap_types[]; + +short ap_type, ap_vendorext; +int poll_delay = 10; void about() { - int nrow = 12, ncol = 47, brow = (LINES - 4 - nrow) / 2, bcol = + int nrow = 14, ncol = 47, brow = (LINES - 5 - nrow) / 2, bcol = (COLS - MCOLS - 2 - ncol) / 2, i; char message[100]; noecho(); curs_set(0); - print_title(_("About")); + print_top(NULL, _("About")); /* drawing the box */ mvwaddch(main_sub, brow, bcol, ACS_ULCORNER); @@ -71,60 +108,53 @@ void about() sprintf(message, _("Version %s"), VERSION); mvwaddstr(main_sub, brow + 3, bcol + 2, message); mvwaddstr(main_sub, brow + 5, bcol + 2, - _("Written by Roman Festchook roma@polesye.net")); + _("Written by Roman Festchook roma@polesye.net")); mvwaddstr(main_sub, brow + 6, bcol + 2, - _("Copyright (c) Roman Festchook 2001-2004")); - mvwaddstr(main_sub, brow + 7, bcol + 2, "http://ap-utils.polesye.net/"); - mvwaddstr(main_sub, brow + 9, bcol + 2, - _("This program is distributed under the terms")); - mvwaddstr(main_sub, brow +10, bcol + 2, - _("of the GNU General Public License version 2.")); + _("and Jan Rafaj jr-aputils@cedric.unob.cz")); + mvwaddstr(main_sub, brow + 7, bcol + 2, + _("Copyright (c) 2001-2006")); + mvwaddstr(main_sub, brow + 8, bcol + 2, + _("Roman Festchook and Jan Rafaj")); + mvwaddstr(main_sub, brow + 9, bcol + 2, "http://ap-utils.polesye.net/"); mvwaddstr(main_sub, brow + 11, bcol + 2, - _("See the included COPYING file for details.")); - + _("This program is distributed under the terms")); + mvwaddstr(main_sub, brow +12, bcol + 2, + _("of the GNU General Public License version 2.")); + mvwaddstr(main_sub, brow + 13, bcol + 2, + _("See the included COPYING file for details.")); wrefresh(main_sub); print_help(ANY_KEY); getch(); print_help(""); - print_title(""); + print_top(NULL, NULL); clear_main(0); return; } void connect_options(unsigned long int ip, int type) { - int i; - struct sockaddr_in client; - unsigned char message[16]; - int fd; + /* + * operAccessPointName OIDs used to retrieve AP NAME [in order of + * corresponding AP MIB types: ATMEL410, NWN, ATMEL12350] + */ + char operAccessPointName[3][12] = { + {0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x0A, 0x00}, + {0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x05, 0x00}, + {0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x01, 0x0A, 0x00} + }; + + extern int atmel410_filter; /* boolean; = 1 if we call from ap-gl utility */ + unsigned char message[256]; + unsigned char label[17]; + int fd, i; char *home_dir; char save_settings=1; - char sysDescr_NWN[] = { 0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00 }; - char sysDescr_ATMEL410[] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, - 0x01, 0x01, 0x01, 0x01, 0x00 }; - char sysDescr_ATMEL12350[] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, - 0x01, 0x01, 0x01, 0x01, 0x00 }; varbind varbinds[1]; - - memset(&client, 0, sizeof client); - client.sin_family = AF_INET; - client.sin_port = INADDR_ANY; - client.sin_addr.s_addr = INADDR_ANY; - - if (sockfd) - close(sockfd); - - if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - print_helperr(CREATE_SOCKET_ERROR); - getch(); - goto exit; - } - - if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1) { - print_helperr(BIND_SOCKET_ERROR); + if (reopen_sockfd() == -1) { + print_helperr(ERR_SOCKET); getch(); goto exit; } @@ -132,10 +162,12 @@ void connect_options(unsigned long int ip, int type) noecho(); curs_set(0); - print_title(_("Connect options")); + print_top(NULL, _("Connect options")); get_all_again: mvwaddstr(main_sub, 1, 1, APIP); + wrefresh(main_sub); + if (ip) { ap_ip.s_addr = ip; mvwaddstr(main_sub, 1, 1 + strlen(APIP), inet_ntoa(ap_ip)); @@ -145,8 +177,12 @@ get_all_again: } mvwaddstr(main_sub, 2, 1, APPASS); + + i = 0; + print_help(""); + print_help(_("Entered characters will not be displayed " - "for security reason.")); + "for security reasons.")); get_pass(message, 2, 1 + strlen(APPASS), 16); if (community) free(community); @@ -154,85 +190,278 @@ get_all_again: community = (char *) malloc(i); strncpy(community, message, i); - print_help(""); - if (type) { + if (type && !atmel410_filter) { + /* entered from ap_search() */ + + /* community already exists */ +/* wattrset(main_sub, A_BOLD); + for(i = 0; community[i++]; waddch(main_sub, '*')); + wattrset(main_sub, A_NORMAL); +*/ ap_type = --type; - mvwaddstr(main_sub, 3, 1, APTYPE); + + print_menusel(3, 1, APTYPE, ap_types[ap_type]); + + /* well, we already know the MIB type, but lets find out MIB ext */ + get_mib_details(); + + /* marks that we want offer AP name -> AP label later */ + i = 1; + + mvwaddstr(main_sub, 4, 1, APVENDOREXT); } else { - mvwaddstr(main_sub, 3, 1, AUTODETECT); - wrefresh(main_sub); - i = yes_no(3, 1 + strlen(AUTODETECT)); - clear_main_new(3, 4); - mvwaddstr(main_sub, 3, 1, APTYPE); - if (i == 2) { /* NO */ + if (atmel410_filter) { + ap_type = --type; + print_menusel(3, 1, APTYPE, ap_types[ap_type]); + ap_vendorext = NONE; /* no need to choose here, really */ + /* marks that we want offer AP name -> AP label later */ + i = 1; + mvwaddstr(main_sub, 4, 1, APVENDOREXT); + } else { + mvwaddstr(main_sub, 3, 1, AUTODETECT); wrefresh(main_sub); - ap_type = menu_choose(3, 1 + strlen(APTYPE), ap_types, 3); - } else { /* YES */ - print_help(_("Determining AP type. Please wait...")); - varbinds[0].oid = sysDescr_NWN; - varbinds[0].len_oid = sizeof(sysDescr_NWN); - varbinds[0].value = NULL; - varbinds[0].len_val = 0; + i = yes_no(3, 1 + strlen(AUTODETECT)); + clear_main_new(3, 4); + mvwaddstr(main_sub, 3, 1, APTYPE); + if (i == 2) { /* NO */ + wrefresh(main_sub); + ap_type = menu_choose(3, 1 + strlen(APTYPE), ap_types, 3); + print_bold(main_sub, ap_types[ap_type]); + mvwaddstr(main_sub, 4, 1, APVENDOREXT); + wrefresh(main_sub); + for (i = 0; ap_vendorexts[ap_type][i]; i++); + if (i == 1) + ap_vendorext = NONE; /* no need to choose here, really */ + else + ap_vendorext = menu_choose(4, 1 + strlen(APVENDOREXT), + ap_vendorexts[ap_type], i); + } else { /* YES */ + if (get_mib_details() == -1) { + clear_main_new(1, 4); + goto get_all_again; + } + print_bold(main_sub, ap_types[ap_type]); + mvwaddstr(main_sub, 4, 1, APVENDOREXT); + } + } + } + print_bold(main_sub, ap_vendorexts[ap_type][ap_vendorext]); + + print_help( + _("This label will be stored on HDD (independently on AP name!).")); + if (i == 1) { + /* + * (being called from ap_search()) or (YES for AP type autodetection) + * => offer possibility to use AP's name as the label + */ + mvwaddstr(main_sub, 5, 1, WANT_SYS_APLABEL); + wrefresh(main_sub); + if (yes_no(5, 1 + strlen(WANT_SYS_APLABEL)) == 1) { /* YES */ + varbinds[0].oid = operAccessPointName[ap_type]; + varbinds[0].len_oid = (ap_type == NWN ? + 8 : sizeof(operAccessPointName[ap_type])); varbinds[0].type = NULL_VALUE; - if (snmp(varbinds, 1, GET) > 0) { - ap_type = NWN; + varbinds[0].len_val = 0; + + print_help(WAIT_RET); + if (snmp(varbinds, i, GET) <= 0) { + print_helperr(ERR_RET); + getch(); } else { - varbinds[0].oid = sysDescr_ATMEL410; - varbinds[0].len_oid = sizeof(sysDescr_ATMEL410); - varbinds[0].value = NULL; - varbinds[0].len_val = 0; - varbinds[0].type = NULL_VALUE; - if (snmp(varbinds, 1, GET) > 0) { - ap_type = ATMEL410; - } else { - varbinds[0].oid = sysDescr_ATMEL12350; - varbinds[0].len_oid = sizeof(sysDescr_ATMEL12350); - varbinds[0].value = NULL; - varbinds[0].len_val = 0; - varbinds[0].type = NULL_VALUE; - if (snmp(varbinds, 1, GET) > 0) { - ap_type = ATMEL12350; - } else { - print_helperr(_("Unable to determine AP type " - "(no response). Press any key.")); - getch(); - clear_main_new(1, 4); - goto get_all_again; - } + clear_main_new(5, 6); + mvwaddstr(main_sub, 5, 1, APLABEL); + wattrset(main_sub, A_BOLD); + for (i = 0; i < varbinds[0].len_val && i < 16 && + *(varbinds[0].value + i); i++) { + label[i] = *(varbinds[0].value + i); + waddch(main_sub, label[i]); + } + label[i] = '\0'; + wattrset(main_sub, A_NORMAL); + if (strlen(varbinds[0].value) > 16) { + print_helperr("Warning! AP LABEL truncated to first 16 characters of AP NAME. Press any key."); + getch(); } } - } - wattrset(main_sub, A_BOLD); + print_help(""); + i = -1; + } } - waddstr(main_sub, ap_types[ap_type]); - wattrset(main_sub, A_NORMAL); - mvwaddstr(main_sub, 4, 1, SAVESETTINGS); + if (i != -1) { /* we have NOT been asked with WANT_SYS_APLABEL */ + clear_main_new(5, 6); + mvwaddstr(main_sub, 5, 1, APLABEL); + wrefresh(main_sub); + get_value(message, 5, 1 + strlen(APLABEL), -sizeof(label), ANY_STRING, + 0, 0, NULL); + strncpy(label, message, strlen(message) + 1); + } + + mvwaddstr(main_sub, 6, 1, SAVESETTINGS); wrefresh(main_sub); - save_settings = on_off(4, 1 + strlen(SAVESETTINGS)); + save_settings = on_off(6, 1 + strlen(SAVESETTINGS)); + clear_main_new(6, 7); + print_menusel(6, 1, SAVESETTINGS, (save_settings == 1) ? ON : OFF); print_bottom(inet_ntoa(ap_ip)); if(save_settings == 1) { if ((home_dir = getenv("HOME"))) { sprintf(message, "%s/.ap-config", home_dir); - if ((fd = open(message, O_CREAT | O_WRONLY | O_APPEND, 0600)) != -1) { - sprintf(message, "%s:%s:%d\n", inet_ntoa(ap_ip), - community, ap_type); + if ((fd = open(message, O_CREAT|O_WRONLY|O_APPEND, 0600)) != -1) { + sprintf(message, "%s:%s:%s:%d:%d\n", inet_ntoa(ap_ip), + community, label, ap_type, ap_vendorext); write(fd, message, strlen(message)); close(fd); - } + wbkgd(main_sub, A_NORMAL); + wrefresh(main_sub); + print_help(DONE_WRITING_APCONF); + } else + print_helperr(ERR_WRITING_APCONF); + + getch(); } } exit: print_help(""); - print_title(""); + print_top(NULL, NULL); clear_main(0); return; } +/* + * Determines AP MIB type (fills ap_type global), and AP MIB vendor extensions + * (fills ap_vendorext global). Returns with -1 on error or 0 + * if everything is OK. + */ +int get_mib_details() +{ + char sysDescr_NWN[] = { + 0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00 + }; + char sysDescr_ATMEL[] = { + 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x01, 0x00 + }; + /* + * ATMEL410: SMARTBRIDGES MIB define this with length 4 (IpAddress); others + * (hopefully) do not define this but eventually return (hopefully) + * different value than 4. + */ + char AuthRadiusIP_ATMEL[] = { + 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x03, 0x00 + }; + /* ATMEL12350: GEMTEK and EZYNET MIBs define length 160, others 92 or 128 */ + char sysDeviceInfo_ATMEL[] = { + 0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x01, 0x01, 0x05, 0x00 + }; + /* ATMEL12350: EZYNET MIB defines length 104, others 88 */ + char wirelessStatistics_ATMEL[] = { + 0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x03, 0x01, 0x00 + }; + + varbind varbinds[2]; + int i; + + print_help(_("Trying to probe AP for MIB properties. Please wait...")); + + /* first, determine the private MIB types according to enterprises ID */ + varbinds[0].oid = sysDescr_NWN; + varbinds[0].len_oid = sizeof(sysDescr_NWN); + varbinds[0].value = NULL; + varbinds[0].len_val = 0; + varbinds[0].type = NULL_VALUE; + if (snmp(varbinds, 1, GET) > 0) { + ap_type = NWN; + } else { + varbinds[0].oid = sysDescr_ATMEL; + varbinds[0].len_oid = sizeof(sysDescr_ATMEL); + varbinds[0].value = NULL; + varbinds[0].len_val = 0; + varbinds[0].type = NULL_VALUE; + if (snmp(varbinds, 1, GET) > 0) { + ap_type = ATMEL410; + } else { + sysDescr_ATMEL[5] = 0xE0; + sysDescr_ATMEL[6] = 0x3E; + varbinds[0].oid = sysDescr_ATMEL; + varbinds[0].len_oid = sizeof(sysDescr_ATMEL); + varbinds[0].value = NULL; + varbinds[0].len_val = 0; + varbinds[0].type = NULL_VALUE; + if (snmp(varbinds, 1, GET) > 0) { + ap_type = ATMEL12350; + } else { + print_helperr(_("Unable to determine AP MIB properties " + "(no response from AP). Press any key.")); + getch(); + return -1; + } + } + } + + /* + * It is best to do the following HERE and FOR ONCE ONLY: find out more + * about specific MIB vendor extensions - we'll check against them + * on different places later. + */ + + ap_vendorext = NONE; + + if (ap_type == ATMEL410) { + varbinds[0].oid = AuthRadiusIP_ATMEL; + varbinds[0].len_oid = sizeof(AuthRadiusIP_ATMEL); + varbinds[0].value = NULL; + varbinds[0].len_val = 0; + varbinds[0].type = NULL_VALUE; + + i = snmp(varbinds, 1, GET); + if (i < 0) { + print_helperr(ERR_RET); + getch(); + return -1; + } + + /* + * i == 0 => 'no such variable in the MIB' returned => + * consider 'ap_vendorext = NONE' too. + */ + + if (varbinds[0].len_val == 4) + ap_vendorext = SBRIDGES; + } + + if (ap_type == ATMEL12350) { + varbinds[0].oid = sysDeviceInfo_ATMEL; + varbinds[0].len_oid = sizeof(sysDeviceInfo_ATMEL); + varbinds[0].value = NULL; + varbinds[0].len_val = 0; + varbinds[0].type = NULL_VALUE; + varbinds[1].oid = wirelessStatistics_ATMEL; + varbinds[1].len_oid = sizeof(wirelessStatistics_ATMEL); + varbinds[1].value = NULL; + varbinds[1].len_val = 0; + varbinds[1].type = NULL_VALUE; + + if (snmp(varbinds, 2, GET) <= 0) { + print_helperr(ERR_RET); + getch(); + return -1; + } + + if (varbinds[0].len_val == 160) + ap_vendorext = GEMTEK; + + if (varbinds[1].len_val == 104) + ap_vendorext = EZYNET; + } + + return 0; +} + void exit_program() { + erase(); + refresh(); endwin(); exit(0); } @@ -246,45 +475,57 @@ void exit_shell() refresh(); } -/* - * Fill channels list string array using regulation domain - * restrictions and return number of the channels +/* + * Sets different-than-default (1 sec.) polling interval for polling-active + * modes, from interval <0.1;86400> seconds. + * poll_delay is natively in tenths of second. */ -int ch_list(int regulation_domain, char **list) +void polling_interval() { - int FIRST_CHANNEL, LAST_CHANNEL, i; - -#ifndef NO_REG_DOMAIN - switch (regulation_domain) { - case 0x10: - case 0x20: - FIRST_CHANNEL = 1; - LAST_CHANNEL = 11; - break; - case 0x30: - FIRST_CHANNEL = 1; - LAST_CHANNEL = 13; - break; - case 0x31: - FIRST_CHANNEL = 10; - LAST_CHANNEL = 11; - break; - case 0x32: - FIRST_CHANNEL = 10; - LAST_CHANNEL = 13; - break; - default: /* also case 0x40 */ -#endif - FIRST_CHANNEL = 1; - LAST_CHANNEL = 14; -#ifndef NO_REG_DOMAIN - } -#endif + unsigned char message[256]; + int c = 0; + + noecho(); + print_help(POLL_HELP); - for (i = 0; i < LAST_CHANNEL - FIRST_CHANNEL + 1; i++) { - list[i] = (char *) malloc(3); - sprintf(list[i], "%02u", FIRST_CHANNEL + i); + while (1) { + sprintf(message, "%s%u", POLL_I, poll_delay); + mvwaddstr(main_sub, 0, 0, message); + sprintf(message, _("(%0.1f seconds)"), (float) poll_delay / 10); + mvwaddstr(main_sub, 1, strlen(POLL_I), message); + wrefresh(main_sub); + c = getch(); + switch (c) { + case 'P': + case 'p': + get_value(message, 0, strlen(POLL_I), 7, INT_STRING, 1, 864000, + POLL_HELP); + poll_delay = atoi(message); + clear_main_new(0, 2); + break; + case 'Q': + case 'q': + goto quit; + } } - return i; + +quit: + print_help(""); + clear_main(0); + return; } +/* + * Expects regulatory domain code on input and returns index of a corresponding + * regdom_types[] member, that describes the given regulatory domain properties. + */ +int regdom_idx(char regdom) +{ + int i; + + for (i = 0; ®dom_types[i]; i++) + if (regdom_types[i].code == regdom) + return i; + + return i; +}