]> git.decadent.org.uk Git - ap-utils.git/blobdiff - lib/common.c
Imported Upstream version 1.5~pre1
[ap-utils.git] / lib / common.c
index e8c0b7c116df502a2dddc700ac82d2339ecc8f9a..9c3b4bec7a3d36203a42594fb9c153aa6423a014 100644 (file)
 #include <sys/ioctl.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;
+char *ap_types[] = {
+    "ATMEL410",
+    "NWN",
+    "ATMEL12350"
+};
+
+char *ap_vendorexts[][3] = {
+    { "NONE", "SBRIDGES" },            /* ATMEL410 exts */
+    { "NONE" },                                /* NWN exts */
+    { "NONE", "TELLUS", "VERNET" }     /* ATMEL12350 exts */
+};
+
+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;
+short ap_type, ap_vendorext;
 extern int sockfd;
 extern struct in_addr ap_ip;
-extern char *ap_types[];
 
 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);
@@ -79,13 +104,17 @@ void about()
     mvwaddstr(main_sub, brow + 5, bcol + 2,
              _("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,
+             _("Portions by Jan Rafaj aputils@cedric.unob.cz"));
+    mvwaddstr(main_sub, brow + 7, bcol + 2,
+             _("Copyright (c) 2001-2004"));
+    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,
              _("This program is distributed under the terms"));
-    mvwaddstr(main_sub, brow +10, bcol + 2,
+    mvwaddstr(main_sub, brow +12, bcol + 2,
              _("of the GNU General Public License version 2."));
-    mvwaddstr(main_sub, brow + 11, bcol + 2,
+    mvwaddstr(main_sub, brow + 13, bcol + 2,
              _("See the included COPYING file for details."));
 
 
@@ -94,20 +123,31 @@ void about()
     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;
+    /*
+     * 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}
+    };
+
     struct sockaddr_in client;
+    extern int atmel410_filter; /* to check is this function called 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;
@@ -132,7 +172,7 @@ 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);
@@ -145,68 +185,144 @@ get_all_again:
     }
 
     mvwaddstr(main_sub, 2, 1, APPASS);
-    print_help(_("Entered characters will not be displayed "
-       "for security reason."));
-    get_pass(message, 2, 1 + strlen(APPASS), 16);
-    if (community)
-       free(community);
-    i = strlen(message) + 1;
-    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);
-    }
 
+    i = 0;
     print_help("");
-    if (type) {
+
+       print_help(_("Entered characters will not be displayed "
+                    "for security reason."));
+       get_pass(message, 2, 1 + strlen(APPASS), 16);
+       if (community)
+           free(community);
+       i = strlen(message) + 1;
+       community = (char *) malloc(i);
+       strncpy(community, message, i);
+
+
+    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, 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);
+
+       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);
+               i = yes_no(3, 1 + strlen(AUTODETECT));
+               clear_main_new(3, 4);
+               mvwaddstr(main_sub, 3, 1, APTYPE);
+               if (i == 2) { /* NO */
+                   char **p;
+    
+                   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, p = ap_vendorexts[ap_type]; *p++; 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);
-       i = yes_no(4, 1 + strlen(AUTODETECT));
-       clear_main_new(4, 5);
-       mvwaddstr(main_sub, 4, 1, APTYPE);
-       if (i == 2) { /* NO */
-           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;
+       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;
+
+           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;
        }
-       wattrset(main_sub, A_BOLD);
     }
-    waddstr(main_sub, ap_types[ap_type]);
-    wattrset(main_sub, A_NORMAL);
 
-    mvwaddstr(main_sub, 5, 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);
+       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));
 
     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);
            }
@@ -214,14 +330,14 @@ get_all_again:
     }
   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
+ * (changes values of ap_vendorext global). Returns with -1 on error or 0
  * if everything is OK.
  */
 int get_mib_details()
@@ -242,6 +358,8 @@ int get_mib_details()
     char oui_sbridges[3] = { 0x00, 0x30, 0x1A };
     char oui_tellus[3] = { 0x00, 0x04, 0xDB };
 
+    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);
@@ -269,8 +387,8 @@ int get_mib_details()
            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;
            }
@@ -282,10 +400,6 @@ int get_mib_details()
      * about specific MIB modifications - we'll use 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);
@@ -306,15 +420,24 @@ int get_mib_details()
         return -1;
     }
 
-    /* detection of different vendor-modified ATMEL private MIBs */
+    /*
+     * Detection of different vendor-modified ATMEL private MIBs.
+     * Note that results here are considered mutually exclusive, although
+     * MIBs *may* share a lot of properties - for example, the condition
+     * for TELLUS is matched also with VERNET firmware, but we want
+     * unambiguous results => exactly one type is to be returned each pass
+     * => the order of these conditions is important.
+     */
+    ap_vendorext = NONE;
+
     if (ap_type == ATMEL410 && (memcmp(oui_sbridges, varbinds[0].value, 3) ==0))
-       IS_ATMEL410_SBRIDGES = 1;
+       ap_vendorext = SBRIDGES;
 
     if (ap_type == ATMEL12350 && (memcmp(oui_tellus, varbinds[0].value, 3) ==0))
-       IS_ATMEL12350_TELLUS = 1;
+       ap_vendorext = TELLUS;
 
     if (ap_type == ATMEL12350 && varbinds[1].len_val == 104)
-       IS_ATMEL12350_VERNET = 1;
+       ap_vendorext = VERNET;
 
     return 0;
 }
@@ -334,45 +457,18 @@ void exit_shell()
     refresh();
 }
 
-/* 
- * Fill channels list string array using regulation domain
- * restrictions and return number of the channels
+/*
+ * Expects regulatory domain code on input and returns index of a corresponding
+ * regdom_types[] member, that describes the given regulatory domain properties.
  */
-int ch_list(int regulation_domain, char **list)
+int regdom_idx(char regdom)
 {
-    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    
+    int i;
+
+    for (i = 0; &regdom_types[i]; i++)
+       if (regdom_types[i].code == regdom)
+           return i;
 
-    for (i = 0; i < LAST_CHANNEL - FIRST_CHANNEL + 1; i++) {
-       list[i] = (char *) malloc(3);
-       sprintf(list[i], "%02u", FIRST_CHANNEL + i);
-    }
     return i;
 }