--- /dev/null
+/*
+ * 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;
+}