]> git.decadent.org.uk Git - ap-utils.git/blobdiff - lib/common.c
Merge commit 'upstream/1.5'
[ap-utils.git] / lib / common.c
index 9c3b4bec7a3d36203a42594fb9c153aa6423a014..a3df8a3a7472fc1e71c11854769f5ea0cea862a5 100644 (file)
@@ -2,6 +2,7 @@
  *      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
@@ -25,6 +26,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
+#include <sys/socket.h>
 #include "ap-utils.h"
 
 #define APIP _("Access Point IP-address: ")
@@ -35,6 +37,8 @@
 #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",
@@ -45,7 +49,8 @@ char *ap_types[] = {
 char *ap_vendorexts[][3] = {
     { "NONE", "SBRIDGES" },            /* ATMEL410 exts */
     { "NONE" },                                /* NWN exts */
-    { "NONE", "TELLUS", "VERNET" }     /* ATMEL12350 exts */
+    { "NONE", "GEMTEK", "EZYNET" },    /* ATMEL12350 exts */
+    { 0 }                              /* do not delete! */
 };
 
 rdprops regdom_types[] = {
@@ -67,10 +72,11 @@ char *channels[] = {
 
 extern WINDOW *main_sub;
 extern char *community, *prog_title;
-short ap_type, ap_vendorext;
-extern int sockfd;
 extern struct in_addr ap_ip;
 
+short ap_type, ap_vendorext;
+int poll_delay = 10;
+
 void about()
 {
     int nrow = 14, ncol = 47, brow = (LINES - 5 - nrow) / 2, bcol =
@@ -102,21 +108,20 @@ 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,
-             _("Portions by Jan Rafaj aputils@cedric.unob.cz"));
+       _("and Jan Rafaj jr-aputils@cedric.unob.cz"));
     mvwaddstr(main_sub, brow + 7, bcol + 2,
-             _("Copyright (c) 2001-2004"));
+       _("Copyright (c) 2001-2005"));
     mvwaddstr(main_sub, brow + 8, bcol + 2,
-             _("Roman Festchook and Jan Rafaj"));
+       _("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"));
+       _("This program is distributed under the terms"));
     mvwaddstr(main_sub, brow +12, bcol + 2,
-             _("of the GNU General Public License version 2."));
+       _("of the GNU General Public License version 2."));
     mvwaddstr(main_sub, brow + 13, bcol + 2,
-             _("See the included COPYING file for details."));
-
+       _("See the included COPYING file for details."));
 
     wrefresh(main_sub);
 
@@ -140,8 +145,7 @@ void connect_options(unsigned long int ip, int type)
       {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 */
+    extern int atmel410_filter; /* boolean; = 1 if we call from ap-gl utility */
     unsigned char message[256];
     unsigned char label[17];
     int fd, i;
@@ -149,22 +153,8 @@ void connect_options(unsigned long int ip, int type)
     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;
     }
@@ -189,17 +179,16 @@ get_all_again:
     i = 0;
     print_help("");
 
-       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(_("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) {
+    if (type && !atmel410_filter) {
        /* entered from ap_search() */
 
        /* community already exists */
@@ -219,47 +208,41 @@ get_all_again:
 
        mvwaddstr(main_sub, 4, 1, APVENDOREXT);
     } else {
-
        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);
+           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),
+           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 */
+               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;
-                   }
+           } 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);
+               mvwaddstr(main_sub, 4, 1, APVENDOREXT);
+           }
        }
     }
-    }
     print_bold(main_sub, ap_vendorexts[ap_type][ap_vendorext]);
 
     print_help(
@@ -291,7 +274,7 @@ get_all_again:
                    label[i] = *(varbinds[0].value + i);
                    waddch(main_sub, label[i]);
                }
-               label[++i] = '\0';
+               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.");
@@ -314,6 +297,8 @@ get_all_again:
     mvwaddstr(main_sub, 6, 1, SAVESETTINGS);
     wrefresh(main_sub);
     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));
 
@@ -325,7 +310,13 @@ get_all_again:
                    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:
@@ -336,8 +327,8 @@ get_all_again:
 }
 
 /*
- * Determines AP MIB type (fills ap_type), and AP MIB vendor extensions
- * (changes values of ap_vendorext global). 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()
@@ -348,15 +339,25 @@ 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
+    };
+    /* 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
     };
-    char Wireless_ATMEL[] = {
-       0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x03, 0x01, 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..."));
 
@@ -397,53 +398,67 @@ int get_mib_details()
 
     /*
      * 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.
      */
-    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;
-    }
 
-    /*
-     * 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))
-       ap_vendorext = SBRIDGES;
+    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 && (memcmp(oui_tellus, varbinds[0].value, 3) ==0))
-       ap_vendorext = TELLUS;
+    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 && varbinds[1].len_val == 104)
-       ap_vendorext = VERNET;
+       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);
 }
@@ -457,6 +472,46 @@ void exit_shell()
     refresh();
 }
 
+/*
+ * 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.
+ */
+void polling_interval()
+{
+    unsigned char message[256];
+    int c = 0;
+
+    noecho();
+    print_help(POLL_HELP);
+
+    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;
+       }
+    }
+
+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.
@@ -471,4 +526,3 @@ int regdom_idx(char regdom)
 
     return i;
 }
-