]> git.decadent.org.uk Git - ap-utils.git/blob - src/ap-rrd.c
Imported Upstream version 1.5.1~pre3
[ap-utils.git] / src / ap-rrd.c
1 /*
2  *      ap-rrd.c from Access Point SNMP Utils for Linux
3  *
4  * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
5  *
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.
9  *
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.
14  *
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
18  *
19  */
20 #include <stdio.h>
21 #include <fcntl.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <sys/ioctl.h>
26 #include <sys/types.h>
27 #if defined (__GLIBC__)
28 #include <libgen.h>
29 #endif
30 #include "ap-utils.h"
31
32 #define ERR_STR _("Error getting data from AP %s\n")
33
34 short ap_type = ATMEL410;
35 char *community = NULL;
36 struct in_addr ap_ip;
37
38 void usage()
39 {
40     printf(_("\nUsage:\n"));
41     printf(_
42           ("\tap-rrd -i ip -c community -t type -d db_file [-b bssid] [-n name] [-a aptype] [-h] [-r] \n\n"));
43     printf(_
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"));
47     printf(_
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"));
50     printf(_
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-2006 Roman Festchook\n\n"),
57            VERSION);
58
59 }
60
61
62 int main(int argc, char **argv)
63 {
64     extern char *optarg;
65     extern int optind;
66     extern int opterr;
67     extern int optopt;
68     int opt = 0;
69
70     struct ap {
71         char mac[6];
72         unsigned char q1;
73         unsigned char q2;
74         unsigned char channel;
75         unsigned char x2;
76         unsigned char options;
77         unsigned char x3[5];
78         unsigned char essid[32];
79     } *app = NULL;
80
81     char Wireless[] =
82         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x03, 0x01,
83         0x00
84     };
85     char EthRx[] =
86         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x07, 0x01,
87         0x00
88     };
89     char EthTx[] =
90         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x07, 0x02,
91         0x00
92     };
93     char operAccessPointName[] =
94         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x0A,
95         0x00
96     };
97     char StasNum[] =
98         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x05, 0x01,
99         0x00
100     };
101     char KnownAP[] =
102         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x07,
103         0x01, 0x00
104     };
105     char bridgeOperationalMode[] =
106         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01,
107         0x01, 0x04, 0x01, 0x00
108     };
109
110     struct EthRxStatistics_s *EthRxStat = NULL;
111     struct EthTxStatistics_s *EthTxStat = NULL;
112     struct wirelessStatistics_s *WirelessStat = NULL;
113     varbind varbinds[2];
114     int i, reset_flag=0;
115     char message[12], bssid_flag,  stat_type = 0, *bssid = NULL, *name = NULL, *rrd_file = NULL, cmd[1024];
116
117 #ifdef HAVE_GETTEXT
118     setlocale(LC_ALL, "");
119     bindtextdomain("ap-utils", LOCALEDIR);
120     textdomain("ap-utils");
121 #endif
122
123     if (argc < 4) {
124         usage();
125         exit(0);
126     }
127
128     do {
129         opterr = 0;
130         switch (opt = getopt(argc, argv, "i:c:t:b:n:a:d:r")) {
131         case 'i':
132             if (inet_aton(optarg, &ap_ip) == 0) {
133                 printf(_("Invalid IP-address\n"));
134                 return 1;
135             }
136             break;
137         case 't':
138             stat_type = optarg[0];
139             break;
140         case 'c':
141             community = malloc(strlen(optarg) + 1);
142             strncpy(community, optarg, strlen(optarg) + 1);
143             break;
144         case 'b':
145             bssid = malloc(strlen(optarg) + 1);
146             strncpy(bssid, optarg, strlen(optarg) + 1);
147             break;
148         case 'd':
149             rrd_file = malloc(strlen(optarg) + 1);
150             strncpy(rrd_file, optarg, strlen(optarg) + 1);
151             break;
152         case 'n':
153             name = malloc(strlen(optarg) + 1);
154             strncpy(name, optarg, strlen(optarg) + 1);
155             break;
156         case 'r':
157             reset_flag=1;
158             break;
159         case 'a':
160             if ( strcmp( optarg, "510\0" ) == 0) {
161               Wireless[5] = 0xE0;
162               Wireless[6] = 0x3E;
163               EthRx[5] = 0xE0;
164               EthRx[6] = 0x3E;
165               EthTx[5] = 0xE0;
166               EthTx[6] = 0x3E;
167               operAccessPointName[5] = 0xE0;
168               operAccessPointName[6] = 0x3E;
169               StasNum[5] = 0xE0;
170               StasNum[6] = 0x3E;
171               KnownAP[5] = 0xE0;
172               KnownAP[6] = 0x3E;
173               bridgeOperationalMode[5] = 0xE0;
174               bridgeOperationalMode[6] = 0x3E;
175             } else if (strcmp(optarg, "410") == 0) {
176               /* nothing - hard-coded defaults are fine */
177             } else {
178               /* Invalid AP-Type */
179               printf(_("Invalid AP-Type '%s' - valid types are 510 or 410\n"), optarg);
180               return 1;
181             }
182             break;
183         case -1:
184             break;
185         default:
186             usage();
187             goto quit;
188         }
189     } while (opt != -1);
190
191     if (!community) {
192         usage();
193         goto quit;
194     }
195
196     switch (stat_type) {
197
198     case 'e':
199
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;
210
211         if (snmp(varbinds, 2, GET) <= 0) {
212             printf(ERR_STR, inet_ntoa(ap_ip));
213             return 1;
214         }
215
216         if (varbinds[0].len_val == 64) {
217             if (EthRxStat)
218                 free(EthRxStat);
219             EthRxStat =
220                 (struct EthRxStatistics_s *) malloc(varbinds[0].
221                                                        len_val);
222             memcpy(EthRxStat, varbinds[0].value, varbinds[0].len_val);
223         } else {
224             printf(ERR_STR, inet_ntoa(ap_ip));
225             return 1;
226         }
227
228         if (varbinds[1].len_val == 56) {
229             if (EthTxStat)
230                 free(EthTxStat);
231             EthTxStat =
232                 (struct EthTxStatistics_s *) malloc(varbinds[1].
233                                                        len_val);
234             memcpy(EthTxStat, varbinds[1].value, varbinds[1].len_val);
235         } else {
236             printf(ERR_STR, inet_ntoa(ap_ip));
237             return 1;
238         }
239         sprintf(cmd, "rrdtool update %s N:%u:%u", rrd_file, swap4(EthRxStat->TotalBytesRx), swap4(EthTxStat->TotalBytesTx));
240         system(cmd);
241         if (EthRxStat)
242             free(EthRxStat);
243         if (EthTxStat)
244             free(EthTxStat);
245         break;
246     case 'w':
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;
252
253         if (snmp(varbinds, 1, GET) <= 0) {
254             printf(ERR_STR, inet_ntoa(ap_ip));
255             return 1;
256         }
257
258         if (varbinds[0].len_val == 88) {
259             if (WirelessStat)
260                 free(WirelessStat);
261             WirelessStat =
262                 (struct wirelessStatistics_s *) malloc(varbinds[0].len_val);
263             memcpy(WirelessStat, varbinds[0].value, varbinds[0].len_val);
264         } else {
265             printf(ERR_STR, inet_ntoa(ap_ip));
266             return 1;
267         }
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));
275         system(cmd);
276         break;
277
278     case 's':
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;
284
285         if (snmp(varbinds, 1, GET) <= 0) {
286             printf(ERR_STR, inet_ntoa(ap_ip));
287             return 1;
288         }
289
290         sprintf(cmd, "rrdtool update %s N:%u", rrd_file, *varbinds[0].value);
291         system(cmd);
292         break;
293
294     case 'l':
295
296         varbinds[0].oid = bridgeOperationalMode;
297         varbinds[0].len_oid = sizeof(bridgeOperationalMode);
298         varbinds[0].len_val = 0;
299         varbinds[0].type = NULL_VALUE;
300
301         if (snmp(varbinds, 1, GET) <= 0) {
302             printf(ERR_STR, inet_ntoa(ap_ip));
303             return 1;
304         }
305
306         if (*(varbinds[0].value) != 3) {
307             printf(ERR_STR, inet_ntoa(ap_ip));
308             return 1;
309         }
310
311         if (reset_flag) {
312                 if (SysReset()) {
313                     printf(ERR_STR, inet_ntoa(ap_ip));
314                     return 1;
315                 }
316                 sleep(10);
317         }
318                 
319         varbinds[0].oid = KnownAP;
320         varbinds[0].len_oid = sizeof(KnownAP);
321         varbinds[0].type = NULL_VALUE;
322         varbinds[0].len_val = 0;
323
324         if (snmp(varbinds, 1, GET) <= 0) {
325             printf(ERR_STR, inet_ntoa(ap_ip));
326             return 1;
327         }
328         bssid_flag = 1;
329         for (i = 0; i < varbinds[0].len_val; i += 48) {
330             if (app)
331                 free(app);
332             app = (struct ap *) malloc(48);
333             memcpy(app, varbinds[0].value + i, 48);
334             if (!app->channel)
335                 continue;
336             if (bssid) {
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))
342                     continue;
343             };
344         sprintf(cmd, "rrdtool update %s N:%u:%u", rrd_file, app->q2, 96 - app->q1);
345         system(cmd);
346             bssid_flag = 0;
347             break;
348         }
349         if (bssid_flag)
350             printf(ERR_STR, inet_ntoa(ap_ip));
351         break;
352     default:
353         usage();
354         goto quit;
355     }
356
357 /*    printf("-\n");
358
359
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) {
366                 printf("\n");
367                 return 1;
368         }
369
370         for (i = 0; i < 32 && *(varbinds[0].value + i); i++)
371                 putchar(*(varbinds[0].value + i));
372                 putchar('\n');
373           if (strncmp(name,varbinds[0].value,strlen(name)) ){
374                 return 2;
375         }
376     } else {
377         printf("-\n");
378     }
379 */
380     
381   quit:
382     if (community)
383         free(community);
384     if (app)
385         free(app);
386     if (bssid)
387         free(bssid);
388     if (name)
389         free(name);
390     return 0;
391 }