]> git.decadent.org.uk Git - ap-utils.git/blob - src/ap-rrd.c
Imported Upstream version 1.5~pre2
[ap-utils.git] / src / ap-rrd.c
1 /*
2  *      ap-mrtg.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_V "\n\n-\n\n"
33 #define ERR_STR_N "999999999\n999999999\n-\n\n"
34
35 short ap_type = ATMEL410;
36 char *community = NULL;
37 int sockfd;
38 struct in_addr ap_ip;
39
40 void usage()
41 {
42     printf(_("\nUsage:\n"));
43     printf(_
44           ("\tap-rrd -i ip -c community -t type -d db_file [-b bssid] [-n name] [-a aptype] [-h] [-r] \n\n"));
45     printf(_
46            ("Get stats from AP and put it in to specified RRDtool database\n\n"));
47     printf(_("-i ip        - AP ip address\n"));
48     printf(_("-c community - SNMP community string\n"));
49     printf(_
50            ("-t type      - statistics type <w>ireless, <e>thernet, associated <s>tations or <l>ink quality in client mode\n"));
51     printf(_("-d db_file   - RRD database file with full path\n"));
52     printf(_
53            ("-b bssid     - mac address of the AP to which get link quality, only if type=l\n"));
54     printf(_("-n name     - AP name - for check only\n")); 
55     printf(_("-a aptype    - AP type - 410 (default) or 510 for ATMEL12350's, like the ME-102\n"));
56     printf(_("-r           - reset AP when getting LinkQuality stats\n"));
57     printf(_("-h           - print this help screen\n\n"));
58     printf(_("ap-rrd %s Copyright (c) 2002-2004 Roman Festchook\n\n"),
59            VERSION);
60
61 }
62
63
64 int main(int argc, char **argv)
65 {
66     extern char *optarg;
67     extern int optind;
68     extern int opterr;
69     extern int optopt;
70     int opt = 0;
71
72     struct ap {
73         char mac[6];
74         unsigned char q1;
75         unsigned char q2;
76         unsigned char channel;
77         unsigned char x2;
78         unsigned char options;
79         unsigned char x3[5];
80         unsigned char essid[32];
81     } *app = NULL;
82
83     char Wireless[] =
84         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x03, 0x01,
85         0x00
86     };
87     char EthRx[] =
88         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x07, 0x01,
89         0x00
90     };
91     char EthTx[] =
92         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x07, 0x02,
93         0x00
94     };
95     char operAccessPointName[] =
96         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x0A,
97         0x00
98     };
99     char StasNum[] =
100         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x05, 0x01,
101         0x00
102     };
103     char KnownAP[] =
104         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x07,
105         0x01, 0x00
106     };
107     char bridgeOperationalMode[] =
108         { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01,
109         0x01, 0x04, 0x01, 0x00
110     };
111
112     struct EthRxStatistics_s *EthRxStat = NULL;
113     struct EthTxStatistics_s *EthTxStat = NULL;
114     struct wirelessStatistics_s *WirelessStat = NULL;
115     varbind varbinds[2];
116     int i, reset_flag=0;
117     char message[12], bssid_flag,  stat_type = 0, *ERR_STR =
118         ERR_STR_N, *bssid = NULL, *name = NULL, *rrd_file = NULL, cmd[1024];
119     struct sockaddr_in client;
120
121 #ifdef HAVE_GETTEXT
122     setlocale(LC_ALL, "");
123     bindtextdomain("ap-utils", LOCALEDIR);
124     textdomain("ap-utils");
125 #endif
126
127     memset(&client, 0, sizeof client);
128     client.sin_family = AF_INET;
129     client.sin_port = INADDR_ANY;
130     client.sin_addr.s_addr = INADDR_ANY;
131
132     if (argc < 4) {
133         usage();
134         exit(0);
135     }
136
137     do {
138         opterr = 0;
139         switch (opt = getopt(argc, argv, "i:c:t:b:n:a:d:r")) {
140         case 'i':
141             if (inet_aton(optarg, &ap_ip) == 0) {
142                 printf(_("Invalid IP-address\n"));
143                 return 1;
144             }
145             break;
146         case 't':
147             stat_type = optarg[0];
148             break;
149         case 'c':
150             community = malloc(strlen(optarg) + 1);
151             strncpy(community, optarg, strlen(optarg) + 1);
152             break;
153         case 'b':
154             bssid = malloc(strlen(optarg) + 1);
155             strncpy(bssid, optarg, strlen(optarg) + 1);
156             break;
157         case 'd':
158             rrd_file = malloc(strlen(optarg) + 1);
159             strncpy(rrd_file, optarg, strlen(optarg) + 1);
160             break;
161         case 'n':
162             name = malloc(strlen(optarg) + 1);
163             strncpy(name, optarg, strlen(optarg) + 1);
164             break;
165         case 'r':
166             reset_flag=1;
167             break;
168         case 'a':
169             if ( strcmp( optarg, "510\0" ) == 0) {
170               Wireless[5] = 0xE0;
171               Wireless[6] = 0x3E;
172               EthRx[5] = 0xE0;
173               EthRx[6] = 0x3E;
174               EthTx[5] = 0xE0;
175               EthTx[6] = 0x3E;
176               operAccessPointName[5] = 0xE0;
177               operAccessPointName[6] = 0x3E;
178               StasNum[5] = 0xE0;
179               StasNum[6] = 0x3E;
180               KnownAP[5] = 0xE0;
181               KnownAP[6] = 0x3E;
182               bridgeOperationalMode[5] = 0xE0;
183               bridgeOperationalMode[6] = 0x3E;
184             } else if (strcmp(optarg, "410") == 0) {
185               /* nothing - hard-coded defaults are fine */
186             } else {
187               /* Invalid AP-Type */
188               printf(_("Invalid AP-Type '%s' - valid types are 510 or 410\n"), optarg);
189               return 1;
190             }
191             break;
192         case -1:
193             break;
194         default:
195             usage();
196             goto quit;
197         }
198     } while (opt != -1);
199
200     if (!community) {
201         usage();
202         goto quit;
203     }
204
205
206     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
207         perror(_("Create socket error"));
208         return 1;
209     }
210     if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1) {
211         perror(_("Bind socket error"));
212         return 1;
213     }
214
215     switch (stat_type) {
216
217     case 'e':
218
219         varbinds[0].oid = EthRx;
220         varbinds[0].len_oid = sizeof(EthRx);
221         varbinds[0].value = EthRx;
222         varbinds[0].len_val = 0;
223         varbinds[0].type = NULL_VALUE;
224         varbinds[1].oid = EthTx;
225         varbinds[1].len_oid = sizeof(EthTx);
226         varbinds[1].value = EthTx;
227         varbinds[1].len_val = 0;
228         varbinds[1].type = NULL_VALUE;
229
230         if (snmp(varbinds, 2, GET) <= 0) {
231             printf(ERR_STR);
232             return 1;
233         }
234
235         if (varbinds[0].len_val == 64) {
236             if (EthRxStat)
237                 free(EthRxStat);
238             EthRxStat =
239                 (struct EthRxStatistics_s *) malloc(varbinds[0].
240                                                        len_val);
241             memcpy(EthRxStat, varbinds[0].value, varbinds[0].len_val);
242         } else {
243             printf(ERR_STR);
244             return 1;
245         }
246
247         if (varbinds[1].len_val == 56) {
248             if (EthTxStat)
249                 free(EthTxStat);
250             EthTxStat =
251                 (struct EthTxStatistics_s *) malloc(varbinds[1].
252                                                        len_val);
253             memcpy(EthTxStat, varbinds[1].value, varbinds[1].len_val);
254         } else {
255             printf(ERR_STR);
256             return 1;
257         }
258         sprintf(cmd, "rrdtool update %s N:%u:%u", rrd_file, swap4(EthRxStat->TotalBytesRx), swap4(EthTxStat->TotalBytesTx));
259         system(cmd);
260         if (EthRxStat)
261             free(EthRxStat);
262         if (EthTxStat)
263             free(EthTxStat);
264         break;
265     case 'w':
266         varbinds[0].oid = Wireless;
267         varbinds[0].len_oid = sizeof(Wireless);
268         varbinds[0].value = Wireless;
269         varbinds[0].len_val = 0;
270         varbinds[0].type = NULL_VALUE;
271
272         if (snmp(varbinds, 1, GET) <= 0) {
273             printf(ERR_STR);
274             return 1;
275         }
276
277         if (varbinds[0].len_val == 88) {
278             if (WirelessStat)
279                 free(WirelessStat);
280             WirelessStat =
281                 (struct wirelessStatistics_s *) malloc(varbinds[0].len_val);
282             memcpy(WirelessStat, varbinds[0].value, varbinds[0].len_val);
283         } else {
284             printf(ERR_STR);
285             return 1;
286         }
287         sprintf(cmd, "rrdtool update %s N:%u:%u", rrd_file,
288                swap4(WirelessStat->UnicastReceivedPackets) +
289                swap4(WirelessStat->BroadcastReceivedPackets) +
290                swap4(WirelessStat->MulticastReceivedPackets),
291                swap4(WirelessStat->UnicastTransmittedPackets) +
292                swap4(WirelessStat->BroadcastTransmittedPackets) +
293                swap4(WirelessStat->MulticastTransmittedPackets));
294         system(cmd);
295         break;
296
297     case 's':
298         varbinds[0].oid = StasNum;
299         varbinds[0].len_oid = sizeof(StasNum);
300         varbinds[0].value = StasNum;
301         varbinds[0].len_val = 0;
302         varbinds[0].type = NULL_VALUE;
303
304         if (snmp(varbinds, 1, GET) <= 0) {
305             printf(ERR_STR);
306             return 1;
307         }
308
309         sprintf(cmd, "rrdtool update %s N:%u", rrd_file, *varbinds[0].value);
310         system(cmd);
311         break;
312
313     case 'l':
314
315         varbinds[0].oid = bridgeOperationalMode;
316         varbinds[0].len_oid = sizeof(bridgeOperationalMode);
317         varbinds[0].len_val = 0;
318         varbinds[0].type = NULL_VALUE;
319
320         if (snmp(varbinds, 1, GET) <= 0) {
321             printf(ERR_STR);
322             return 1;
323         }
324
325         if (*(varbinds[0].value) != 3) {
326             printf(ERR_STR);
327             return 1;
328         }
329
330         if (reset_flag) {
331                 if (SysReset()) {
332                     printf(ERR_STR);
333                     return 1;
334                 }
335                 sleep(10);
336         }
337                 
338         varbinds[0].oid = KnownAP;
339         varbinds[0].len_oid = sizeof(KnownAP);
340         varbinds[0].type = NULL_VALUE;
341         varbinds[0].len_val = 0;
342
343         if (snmp(varbinds, 1, GET) <= 0) {
344             printf(ERR_STR);
345             return 1;
346         }
347         bssid_flag = 1;
348         for (i = 0; i < varbinds[0].len_val; i += 48) {
349             if (app)
350                 free(app);
351             app = (struct ap *) malloc(48);
352             memcpy(app, varbinds[0].value + i, 48);
353             if (!app->channel)
354                 continue;
355             if (bssid) {
356                 sprintf(message, "%02X%02X%02X%02X%02X%02X",
357                         app->mac[0] & 0xFF, app->mac[1] & 0xFF,
358                         app->mac[2] & 0xFF, app->mac[3] & 0xFF,
359                         app->mac[4] & 0xFF, app->mac[5] & 0xFF);
360                 if (memcmp(message, bssid, 12))
361                     continue;
362             };
363         sprintf(cmd, "rrdtool update %s N:%u:%u", rrd_file, app->q2, 96 - app->q1);
364         system(cmd);
365             bssid_flag = 0;
366             break;
367         }
368         if (bssid_flag)
369             printf(ERR_STR);
370         break;
371     default:
372         usage();
373         goto quit;
374     }
375
376 /*    printf("-\n");
377
378
379     if ( name != NULL ) {
380         varbinds[0].oid = operAccessPointName;
381         varbinds[0].len_oid = sizeof(operAccessPointName);
382         varbinds[0].len_val = 0;
383         varbinds[0].type = NULL_VALUE;
384         if (snmp(varbinds, 1, GET) <= 0) {
385                 printf("\n");
386                 return 1;
387         }
388
389         for (i = 0; i < 32 && *(varbinds[0].value + i); i++)
390                 putchar(*(varbinds[0].value + i));
391                 putchar('\n');
392           if (strncmp(name,varbinds[0].value,strlen(name)) ){
393                 return 2;
394         }
395     } else {
396         printf("-\n");
397     }
398 */
399     close(sockfd);
400
401     
402   quit:
403     if (community)
404         free(community);
405     if (app)
406         free(app);
407     if (bssid)
408         free(bssid);
409     if (name)
410         free(name);
411     return 0;
412 }
413