* common.c from Access Point SNMP Utils for Linux
*
* Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
+ * Copyright (c) 2005 Jan Rafaj <jr-aputils at cedric dot unob dot cz>
*
* 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
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
+#include <sys/socket.h>
#include "ap-utils.h"
-#define AUTODETECT _("Autodetect AP type? ")
#define APIP _("Access Point IP-address: ")
#define APPASS _("Password (community): ")
-#define APNAME _("Access Point name: ")
-#define WANT_APNAME _("Do you want to define name for this AP? ")
-#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: ")
-
-char IS_ATMEL410_SBRIDGES;
-char IS_ATMEL12350_TELLUS;
-char IS_ATMEL12350_VERNET;
+#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);
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-2005"));
+ 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;
+ /*
+ * 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 name[17];
- int fd;
+ unsigned char label[17];
+ int fd, i;
char *home_dir;
char save_settings=1;
+ 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;
}
noecho();
curs_set(0);
- print_title(_("Connect options"));
+ print_top(NULL, _("Connect options"));
get_all_again:
mvwaddstr(main_sub, 1, 1, APIP);
}
mvwaddstr(main_sub, 2, 1, APPASS);
+
+ i = 0;
+ print_help("");
+
print_help(_("Entered characters will not be displayed "
- "for security reason."));
+ "for security reason."));
get_pass(message, 2, 1 + strlen(APPASS), 16);
if (community)
free(community);
community = (char *) malloc(i);
strncpy(community, message, i);
- print_help(_("Display name for the Access point "
- "(NOT the name defined inside the AP!)"));
- mvwaddstr(main_sub, 3, 1, WANT_APNAME);
- wrefresh(main_sub);
- i = yes_no(3, 1 + strlen(WANT_APNAME));
- if (i == 2) { /* NO */
- name[0] = '\0';
- mvwaddstr(main_sub, 3, 1 + strlen(WANT_APNAME), "No");
- } else { /* YES */
- clear_main_new(3, 4);
- mvwaddstr(main_sub, 3, 1, APNAME);
- get_value(message, 3, 1 + strlen(APNAME), sizeof(name),
- ANY_STRING, 0, 0, NULL);
- strncpy(name, message, strlen(message) + 1);
- }
+ if (type && !atmel410_filter) {
+ /* entered from ap_search() */
- print_help("");
- if (type) {
+ /* 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, 4, 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, 4, 1, AUTODETECT);
- wrefresh(main_sub);
- i = yes_no(4, 1 + strlen(AUTODETECT));
- clear_main_new(4, 5);
- mvwaddstr(main_sub, 4, 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(4, 1 + strlen(APTYPE), ap_types, 3);
- } else { /* YES */
- print_help(_("Determining AP type. Please wait..."));
- if (get_mib_details() == -1) {
- clear_main_new(1, 5);
- goto get_all_again;
+ 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);
}
}
- wattrset(main_sub, A_BOLD);
}
- waddstr(main_sub, ap_types[ap_type]);
- wattrset(main_sub, A_NORMAL);
+ 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;
+ varbinds[0].len_val = 0;
- mvwaddstr(main_sub, 5, 1, SAVESETTINGS);
+ print_help(WAIT_RET);
+ if (snmp(varbinds, i, GET) <= 0) {
+ print_helperr(ERR_RET);
+ getch();
+ } else {
+ 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();
+ }
+ }
+ print_help("");
+ i = -1;
+ }
+ }
+
+ if (i != -1) { /* we have NOT been asked with WANT_SYS_APLABEL */
+ clear_main_new(5, 6);
+ mvwaddstr(main_sub, 5, 1, APLABEL);
+ 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(5, 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:%s:%d\n", inet_ntoa(ap_ip),
- community, name, 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), and AP MIB vendor extensions
- * (changes values of IS_ATMEL* globals). Returns with -1 on error or 0
+ * 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_ATMEL[] = {
0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x01, 0x00
};
- char operEthernetAddress_ATMEL[] = {
- 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x02, 0x03, 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
};
- char Wireless_ATMEL[] = {
- 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x03, 0x01, 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];
- char oui_sbridges[3] = { 0x00, 0x30, 0x1A };
- char oui_tellus[3] = { 0x00, 0x04, 0xDB };
+ 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;
if (snmp(varbinds, 1, GET) > 0) {
ap_type = ATMEL12350;
} else {
- print_helperr(_("Unable to determine AP type "
- "(no response). Press any key."));
+ 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 modifications - we'll use them on different places
- * later.
+ * about specific MIB vendor extensions - we'll check against them
+ * on different places later.
*/
- IS_ATMEL410_SBRIDGES = 0;
- IS_ATMEL12350_TELLUS = 0;
- IS_ATMEL12350_VERNET = 0;
- varbinds[0].type = NULL_VALUE;
- varbinds[0].oid = operEthernetAddress_ATMEL;
- varbinds[0].len_oid = sizeof(operEthernetAddress_ATMEL);
- varbinds[0].len_val = 0;
- varbinds[1].type = NULL_VALUE;
- varbinds[1].oid = Wireless_ATMEL;
- varbinds[1].len_oid = sizeof(Wireless_ATMEL);
- varbinds[1].len_val = 0;
- if (ap_type == ATMEL12350) {
- operEthernetAddress_ATMEL[5] = 0xE0;
- operEthernetAddress_ATMEL[6] = 0x3E;
- Wireless_ATMEL[5] = 0xE0;
- Wireless_ATMEL[6] = 0x3E;
- }
- if (snmp(varbinds, 2, GET) <= 0) {
- print_helperr(ERR_RET);
- getch();
- return -1;
+ 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;
}
- /* detection of different vendor-modified ATMEL private MIBs */
- if (ap_type == ATMEL410 && (memcmp(oui_sbridges, varbinds[0].value, 3) ==0))
- IS_ATMEL410_SBRIDGES = 1;
+ 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 (ap_type == ATMEL12350 && (memcmp(oui_tellus, varbinds[0].value, 3) ==0))
- IS_ATMEL12350_TELLUS = 1;
+ if (varbinds[0].len_val == 160)
+ ap_vendorext = GEMTEK;
- if (ap_type == ATMEL12350 && varbinds[1].len_val == 104)
- IS_ATMEL12350_VERNET = 1;
+ if (varbinds[1].len_val == 104)
+ ap_vendorext = EZYNET;
+ }
return 0;
}
void exit_program()
{
+ erase();
+ refresh();
endwin();
exit(0);
}
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;
+}