]> git.decadent.org.uk Git - ap-utils.git/blobdiff - src/ap-rrd.c
Merge commit 'upstream/1.5'
[ap-utils.git] / src / ap-rrd.c
diff --git a/src/ap-rrd.c b/src/ap-rrd.c
new file mode 100644 (file)
index 0000000..9b15269
--- /dev/null
@@ -0,0 +1,391 @@
+/*
+ *      ap-rrd.c from Access Point SNMP Utils for Linux
+ *
+ * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
+ *
+ * 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
+ * June 1991 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#if defined (__GLIBC__)
+#include <libgen.h>
+#endif
+#include "ap-utils.h"
+
+#define ERR_STR _("Error getting data from AP %s\n")
+
+short ap_type = ATMEL410;
+char *community = NULL;
+struct in_addr ap_ip;
+
+void usage()
+{
+    printf(_("\nUsage:\n"));
+    printf(_
+          ("\tap-rrd -i ip -c community -t type -d db_file [-b bssid] [-n name] [-a aptype] [-h] [-r] \n\n"));
+    printf(_
+          ("Get stats from AP and put it in to specified RRDtool database\n\n"));
+    printf(_("-i ip        - AP ip address\n"));
+    printf(_("-c community - SNMP community string\n"));
+    printf(_
+          ("-t type      - statistics type <w>ireless, <e>thernet, associated <s>tations or <l>ink quality in client mode\n"));
+    printf(_("-d db_file   - RRD database file with full path\n"));
+    printf(_
+          ("-b bssid     - mac address of the AP to which get link quality, only if type=l\n"));
+    printf(_("-n name     - AP name - for check only\n")); 
+    printf(_("-a aptype    - AP type - 410 (default) or 510 for ATMEL12350's, like the ME-102\n"));
+    printf(_("-r           - reset AP when getting LinkQuality stats\n"));
+    printf(_("-h           - print this help screen\n\n"));
+    printf(_("ap-rrd %s Copyright (c) 2002-2004 Roman Festchook\n\n"),
+          VERSION);
+
+}
+
+
+int main(int argc, char **argv)
+{
+    extern char *optarg;
+    extern int optind;
+    extern int opterr;
+    extern int optopt;
+    int opt = 0;
+
+    struct ap {
+       char mac[6];
+       unsigned char q1;
+       unsigned char q2;
+       unsigned char channel;
+       unsigned char x2;
+       unsigned char options;
+       unsigned char x3[5];
+       unsigned char essid[32];
+    } *app = NULL;
+
+    char Wireless[] =
+       { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x03, 0x01,
+       0x00
+    };
+    char EthRx[] =
+       { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x07, 0x01,
+       0x00
+    };
+    char EthTx[] =
+       { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x07, 0x02,
+       0x00
+    };
+    char operAccessPointName[] =
+       { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x0A,
+       0x00
+    };
+    char StasNum[] =
+       { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x05, 0x01,
+       0x00
+    };
+    char KnownAP[] =
+       { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x07,
+       0x01, 0x00
+    };
+    char bridgeOperationalMode[] =
+       { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01,
+       0x01, 0x04, 0x01, 0x00
+    };
+
+    struct EthRxStatistics_s *EthRxStat = NULL;
+    struct EthTxStatistics_s *EthTxStat = NULL;
+    struct wirelessStatistics_s *WirelessStat = NULL;
+    varbind varbinds[2];
+    int i, reset_flag=0;
+    char message[12], bssid_flag,  stat_type = 0, *bssid = NULL, *name = NULL, *rrd_file = NULL, cmd[1024];
+
+#ifdef HAVE_GETTEXT
+    setlocale(LC_ALL, "");
+    bindtextdomain("ap-utils", LOCALEDIR);
+    textdomain("ap-utils");
+#endif
+
+    if (argc < 4) {
+       usage();
+       exit(0);
+    }
+
+    do {
+       opterr = 0;
+       switch (opt = getopt(argc, argv, "i:c:t:b:n:a:d:r")) {
+       case 'i':
+           if (inet_aton(optarg, &ap_ip) == 0) {
+               printf(_("Invalid IP-address\n"));
+               return 1;
+           }
+           break;
+       case 't':
+           stat_type = optarg[0];
+           break;
+       case 'c':
+           community = malloc(strlen(optarg) + 1);
+           strncpy(community, optarg, strlen(optarg) + 1);
+           break;
+       case 'b':
+           bssid = malloc(strlen(optarg) + 1);
+           strncpy(bssid, optarg, strlen(optarg) + 1);
+           break;
+       case 'd':
+           rrd_file = malloc(strlen(optarg) + 1);
+           strncpy(rrd_file, optarg, strlen(optarg) + 1);
+           break;
+       case 'n':
+           name = malloc(strlen(optarg) + 1);
+           strncpy(name, optarg, strlen(optarg) + 1);
+           break;
+       case 'r':
+           reset_flag=1;
+           break;
+        case 'a':
+            if ( strcmp( optarg, "510\0" ) == 0) {
+              Wireless[5] = 0xE0;
+              Wireless[6] = 0x3E;
+              EthRx[5] = 0xE0;
+              EthRx[6] = 0x3E;
+              EthTx[5] = 0xE0;
+              EthTx[6] = 0x3E;
+              operAccessPointName[5] = 0xE0;
+              operAccessPointName[6] = 0x3E;
+              StasNum[5] = 0xE0;
+              StasNum[6] = 0x3E;
+              KnownAP[5] = 0xE0;
+              KnownAP[6] = 0x3E;
+              bridgeOperationalMode[5] = 0xE0;
+              bridgeOperationalMode[6] = 0x3E;
+            } else if (strcmp(optarg, "410") == 0) {
+              /* nothing - hard-coded defaults are fine */
+            } else {
+              /* Invalid AP-Type */
+              printf(_("Invalid AP-Type '%s' - valid types are 510 or 410\n"), optarg);
+              return 1;
+            }
+            break;
+       case -1:
+            break;
+       default:
+           usage();
+           goto quit;
+       }
+    } while (opt != -1);
+
+    if (!community) {
+       usage();
+       goto quit;
+    }
+
+    switch (stat_type) {
+
+    case 'e':
+
+       varbinds[0].oid = EthRx;
+       varbinds[0].len_oid = sizeof(EthRx);
+       varbinds[0].value = EthRx;
+       varbinds[0].len_val = 0;
+       varbinds[0].type = NULL_VALUE;
+       varbinds[1].oid = EthTx;
+       varbinds[1].len_oid = sizeof(EthTx);
+       varbinds[1].value = EthTx;
+       varbinds[1].len_val = 0;
+       varbinds[1].type = NULL_VALUE;
+
+       if (snmp(varbinds, 2, GET) <= 0) {
+           printf(ERR_STR, inet_ntoa(ap_ip));
+           return 1;
+       }
+
+       if (varbinds[0].len_val == 64) {
+           if (EthRxStat)
+               free(EthRxStat);
+           EthRxStat =
+               (struct EthRxStatistics_s *) malloc(varbinds[0].
+                                                      len_val);
+           memcpy(EthRxStat, varbinds[0].value, varbinds[0].len_val);
+       } else {
+           printf(ERR_STR, inet_ntoa(ap_ip));
+           return 1;
+       }
+
+       if (varbinds[1].len_val == 56) {
+           if (EthTxStat)
+               free(EthTxStat);
+           EthTxStat =
+               (struct EthTxStatistics_s *) malloc(varbinds[1].
+                                                      len_val);
+           memcpy(EthTxStat, varbinds[1].value, varbinds[1].len_val);
+       } else {
+           printf(ERR_STR, inet_ntoa(ap_ip));
+           return 1;
+       }
+       sprintf(cmd, "rrdtool update %s N:%u:%u", rrd_file, swap4(EthRxStat->TotalBytesRx), swap4(EthTxStat->TotalBytesTx));
+       system(cmd);
+       if (EthRxStat)
+           free(EthRxStat);
+       if (EthTxStat)
+           free(EthTxStat);
+       break;
+    case 'w':
+       varbinds[0].oid = Wireless;
+       varbinds[0].len_oid = sizeof(Wireless);
+       varbinds[0].value = Wireless;
+       varbinds[0].len_val = 0;
+       varbinds[0].type = NULL_VALUE;
+
+       if (snmp(varbinds, 1, GET) <= 0) {
+           printf(ERR_STR, inet_ntoa(ap_ip));
+           return 1;
+       }
+
+       if (varbinds[0].len_val == 88) {
+           if (WirelessStat)
+               free(WirelessStat);
+           WirelessStat =
+               (struct wirelessStatistics_s *) malloc(varbinds[0].len_val);
+           memcpy(WirelessStat, varbinds[0].value, varbinds[0].len_val);
+       } else {
+           printf(ERR_STR, inet_ntoa(ap_ip));
+           return 1;
+       }
+       sprintf(cmd, "rrdtool update %s N:%u:%u", rrd_file,
+              swap4(WirelessStat->UnicastReceivedPackets) +
+              swap4(WirelessStat->BroadcastReceivedPackets) +
+              swap4(WirelessStat->MulticastReceivedPackets),
+              swap4(WirelessStat->UnicastTransmittedPackets) +
+              swap4(WirelessStat->BroadcastTransmittedPackets) +
+              swap4(WirelessStat->MulticastTransmittedPackets));
+       system(cmd);
+       break;
+
+    case 's':
+       varbinds[0].oid = StasNum;
+       varbinds[0].len_oid = sizeof(StasNum);
+       varbinds[0].value = StasNum;
+       varbinds[0].len_val = 0;
+       varbinds[0].type = NULL_VALUE;
+
+       if (snmp(varbinds, 1, GET) <= 0) {
+           printf(ERR_STR, inet_ntoa(ap_ip));
+           return 1;
+       }
+
+       sprintf(cmd, "rrdtool update %s N:%u", rrd_file, *varbinds[0].value);
+       system(cmd);
+       break;
+
+    case 'l':
+
+       varbinds[0].oid = bridgeOperationalMode;
+       varbinds[0].len_oid = sizeof(bridgeOperationalMode);
+       varbinds[0].len_val = 0;
+       varbinds[0].type = NULL_VALUE;
+
+       if (snmp(varbinds, 1, GET) <= 0) {
+           printf(ERR_STR, inet_ntoa(ap_ip));
+           return 1;
+       }
+
+       if (*(varbinds[0].value) != 3) {
+           printf(ERR_STR, inet_ntoa(ap_ip));
+           return 1;
+       }
+
+       if (reset_flag) {
+               if (SysReset()) {
+                   printf(ERR_STR, inet_ntoa(ap_ip));
+                   return 1;
+               }
+               sleep(10);
+       }
+               
+       varbinds[0].oid = KnownAP;
+       varbinds[0].len_oid = sizeof(KnownAP);
+       varbinds[0].type = NULL_VALUE;
+       varbinds[0].len_val = 0;
+
+       if (snmp(varbinds, 1, GET) <= 0) {
+           printf(ERR_STR, inet_ntoa(ap_ip));
+           return 1;
+       }
+       bssid_flag = 1;
+       for (i = 0; i < varbinds[0].len_val; i += 48) {
+           if (app)
+               free(app);
+           app = (struct ap *) malloc(48);
+           memcpy(app, varbinds[0].value + i, 48);
+           if (!app->channel)
+               continue;
+           if (bssid) {
+               sprintf(message, "%02X%02X%02X%02X%02X%02X",
+                       app->mac[0] & 0xFF, app->mac[1] & 0xFF,
+                       app->mac[2] & 0xFF, app->mac[3] & 0xFF,
+                       app->mac[4] & 0xFF, app->mac[5] & 0xFF);
+               if (memcmp(message, bssid, 12))
+                   continue;
+           };
+       sprintf(cmd, "rrdtool update %s N:%u:%u", rrd_file, app->q2, 96 - app->q1);
+       system(cmd);
+           bssid_flag = 0;
+           break;
+       }
+       if (bssid_flag)
+           printf(ERR_STR, inet_ntoa(ap_ip));
+       break;
+    default:
+       usage();
+       goto quit;
+    }
+
+/*    printf("-\n");
+
+
+    if ( name != NULL ) {
+        varbinds[0].oid = operAccessPointName;
+        varbinds[0].len_oid = sizeof(operAccessPointName);
+        varbinds[0].len_val = 0;
+        varbinds[0].type = NULL_VALUE;
+        if (snmp(varbinds, 1, GET) <= 0) {
+               printf("\n");
+               return 1;
+        }
+
+        for (i = 0; i < 32 && *(varbinds[0].value + i); i++)
+               putchar(*(varbinds[0].value + i));
+               putchar('\n');
+          if (strncmp(name,varbinds[0].value,strlen(name)) ){
+               return 2;
+        }
+    } else {
+        printf("-\n");
+    }
+*/
+    
+  quit:
+    if (community)
+       free(community);
+    if (app)
+       free(app);
+    if (bssid)
+       free(bssid);
+    if (name)
+       free(name);
+    return 0;
+}