2 * ap-rrd.c from Access Point SNMP Utils for Linux
4 * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License Version 2 from
8 * June 1991 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <sys/ioctl.h>
26 #include <sys/types.h>
27 #if defined (__GLIBC__)
32 #define ERR_STR _("Error getting data from AP %s\n")
34 short ap_type = ATMEL410;
35 char *community = NULL;
40 printf(_("\nUsage:\n"));
42 ("\tap-rrd -i ip -c community -t type -d db_file [-b bssid] [-n name] [-a aptype] [-h] [-r] \n\n"));
44 ("Get stats from AP and put it in to specified RRDtool database\n\n"));
45 printf(_("-i ip - AP ip address\n"));
46 printf(_("-c community - SNMP community string\n"));
48 ("-t type - statistics type <w>ireless, <e>thernet, associated <s>tations or <l>ink quality in client mode\n"));
49 printf(_("-d db_file - RRD database file with full path\n"));
51 ("-b bssid - mac address of the AP to which get link quality, only if type=l\n"));
52 printf(_("-n name - AP name - for check only\n"));
53 printf(_("-a aptype - AP type - 410 (default) or 510 for ATMEL12350's, like the ME-102\n"));
54 printf(_("-r - reset AP when getting LinkQuality stats\n"));
55 printf(_("-h - print this help screen\n\n"));
56 printf(_("ap-rrd %s Copyright (c) 2002-2004 Roman Festchook\n\n"),
62 int main(int argc, char **argv)
74 unsigned char channel;
76 unsigned char options;
78 unsigned char essid[32];
82 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x03, 0x01,
86 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x07, 0x01,
90 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x07, 0x02,
93 char operAccessPointName[] =
94 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x0A,
98 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x05, 0x01,
102 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x07,
105 char bridgeOperationalMode[] =
106 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01,
107 0x01, 0x04, 0x01, 0x00
110 struct EthRxStatistics_s *EthRxStat = NULL;
111 struct EthTxStatistics_s *EthTxStat = NULL;
112 struct wirelessStatistics_s *WirelessStat = NULL;
115 char message[12], bssid_flag, stat_type = 0, *bssid = NULL, *name = NULL, *rrd_file = NULL, cmd[1024];
118 setlocale(LC_ALL, "");
119 bindtextdomain("ap-utils", LOCALEDIR);
120 textdomain("ap-utils");
130 switch (opt = getopt(argc, argv, "i:c:t:b:n:a:d:r")) {
132 if (inet_aton(optarg, &ap_ip) == 0) {
133 printf(_("Invalid IP-address\n"));
138 stat_type = optarg[0];
141 community = malloc(strlen(optarg) + 1);
142 strncpy(community, optarg, strlen(optarg) + 1);
145 bssid = malloc(strlen(optarg) + 1);
146 strncpy(bssid, optarg, strlen(optarg) + 1);
149 rrd_file = malloc(strlen(optarg) + 1);
150 strncpy(rrd_file, optarg, strlen(optarg) + 1);
153 name = malloc(strlen(optarg) + 1);
154 strncpy(name, optarg, strlen(optarg) + 1);
160 if ( strcmp( optarg, "510\0" ) == 0) {
167 operAccessPointName[5] = 0xE0;
168 operAccessPointName[6] = 0x3E;
173 bridgeOperationalMode[5] = 0xE0;
174 bridgeOperationalMode[6] = 0x3E;
175 } else if (strcmp(optarg, "410") == 0) {
176 /* nothing - hard-coded defaults are fine */
178 /* Invalid AP-Type */
179 printf(_("Invalid AP-Type '%s' - valid types are 510 or 410\n"), optarg);
200 varbinds[0].oid = EthRx;
201 varbinds[0].len_oid = sizeof(EthRx);
202 varbinds[0].value = EthRx;
203 varbinds[0].len_val = 0;
204 varbinds[0].type = NULL_VALUE;
205 varbinds[1].oid = EthTx;
206 varbinds[1].len_oid = sizeof(EthTx);
207 varbinds[1].value = EthTx;
208 varbinds[1].len_val = 0;
209 varbinds[1].type = NULL_VALUE;
211 if (snmp(varbinds, 2, GET) <= 0) {
212 printf(ERR_STR, inet_ntoa(ap_ip));
216 if (varbinds[0].len_val == 64) {
220 (struct EthRxStatistics_s *) malloc(varbinds[0].
222 memcpy(EthRxStat, varbinds[0].value, varbinds[0].len_val);
224 printf(ERR_STR, inet_ntoa(ap_ip));
228 if (varbinds[1].len_val == 56) {
232 (struct EthTxStatistics_s *) malloc(varbinds[1].
234 memcpy(EthTxStat, varbinds[1].value, varbinds[1].len_val);
236 printf(ERR_STR, inet_ntoa(ap_ip));
239 sprintf(cmd, "rrdtool update %s N:%u:%u", rrd_file, swap4(EthRxStat->TotalBytesRx), swap4(EthTxStat->TotalBytesTx));
247 varbinds[0].oid = Wireless;
248 varbinds[0].len_oid = sizeof(Wireless);
249 varbinds[0].value = Wireless;
250 varbinds[0].len_val = 0;
251 varbinds[0].type = NULL_VALUE;
253 if (snmp(varbinds, 1, GET) <= 0) {
254 printf(ERR_STR, inet_ntoa(ap_ip));
258 if (varbinds[0].len_val == 88) {
262 (struct wirelessStatistics_s *) malloc(varbinds[0].len_val);
263 memcpy(WirelessStat, varbinds[0].value, varbinds[0].len_val);
265 printf(ERR_STR, inet_ntoa(ap_ip));
268 sprintf(cmd, "rrdtool update %s N:%u:%u", rrd_file,
269 swap4(WirelessStat->UnicastReceivedPackets) +
270 swap4(WirelessStat->BroadcastReceivedPackets) +
271 swap4(WirelessStat->MulticastReceivedPackets),
272 swap4(WirelessStat->UnicastTransmittedPackets) +
273 swap4(WirelessStat->BroadcastTransmittedPackets) +
274 swap4(WirelessStat->MulticastTransmittedPackets));
279 varbinds[0].oid = StasNum;
280 varbinds[0].len_oid = sizeof(StasNum);
281 varbinds[0].value = StasNum;
282 varbinds[0].len_val = 0;
283 varbinds[0].type = NULL_VALUE;
285 if (snmp(varbinds, 1, GET) <= 0) {
286 printf(ERR_STR, inet_ntoa(ap_ip));
290 sprintf(cmd, "rrdtool update %s N:%u", rrd_file, *varbinds[0].value);
296 varbinds[0].oid = bridgeOperationalMode;
297 varbinds[0].len_oid = sizeof(bridgeOperationalMode);
298 varbinds[0].len_val = 0;
299 varbinds[0].type = NULL_VALUE;
301 if (snmp(varbinds, 1, GET) <= 0) {
302 printf(ERR_STR, inet_ntoa(ap_ip));
306 if (*(varbinds[0].value) != 3) {
307 printf(ERR_STR, inet_ntoa(ap_ip));
313 printf(ERR_STR, inet_ntoa(ap_ip));
319 varbinds[0].oid = KnownAP;
320 varbinds[0].len_oid = sizeof(KnownAP);
321 varbinds[0].type = NULL_VALUE;
322 varbinds[0].len_val = 0;
324 if (snmp(varbinds, 1, GET) <= 0) {
325 printf(ERR_STR, inet_ntoa(ap_ip));
329 for (i = 0; i < varbinds[0].len_val; i += 48) {
332 app = (struct ap *) malloc(48);
333 memcpy(app, varbinds[0].value + i, 48);
337 sprintf(message, "%02X%02X%02X%02X%02X%02X",
338 app->mac[0] & 0xFF, app->mac[1] & 0xFF,
339 app->mac[2] & 0xFF, app->mac[3] & 0xFF,
340 app->mac[4] & 0xFF, app->mac[5] & 0xFF);
341 if (memcmp(message, bssid, 12))
344 sprintf(cmd, "rrdtool update %s N:%u:%u", rrd_file, app->q2, 96 - app->q1);
350 printf(ERR_STR, inet_ntoa(ap_ip));
360 if ( name != NULL ) {
361 varbinds[0].oid = operAccessPointName;
362 varbinds[0].len_oid = sizeof(operAccessPointName);
363 varbinds[0].len_val = 0;
364 varbinds[0].type = NULL_VALUE;
365 if (snmp(varbinds, 1, GET) <= 0) {
370 for (i = 0; i < 32 && *(varbinds[0].value + i); i++)
371 putchar(*(varbinds[0].value + i));
373 if (strncmp(name,varbinds[0].value,strlen(name)) ){