2 * ap-mrtg.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_V "\n\n-\n\n"
33 #define ERR_STR_N "999999999\n999999999\n-\n\n"
35 short ap_type = ATMEL410;
36 char *community = NULL;
42 printf(_("\nUsage:\n"));
44 ("\tap-mrtg -i ip -c community -t type [-b bssid] [-n name] [-a aptype] [-v] [-h] [-r]\n\n"));
46 ("Get stats from AP and return it in MRTG parsable format\n\n"));
47 printf(_("-i ip - AP ip address\n"));
48 printf(_("-c community - SNMP community string\n"));
50 ("-t type - statistics type <w>ireless, <e>thernet, associated <s>tations or <l>ink quality in client mode\n"));
52 ("-b bssid - mac address of the AP to which get link quality, only if type=l\n"));
53 printf(_("-n name - AP name - for check only\n"));
54 printf(_("-a aptype - AP type - 410 (default) or 510 for ATMEL12350's, like the ME-102\n"));
56 ("-v - report MRTG about problems connecting to AP\n"));
57 printf(_("-r - reset AP when getting LinkQuality stats\n"));
58 printf(_("-h - print this help screen\n\n"));
59 printf(_("ap-mrtg %s Copyright (c) 2002-2003 Roman Festchook\n\n"),
65 int main(int argc, char **argv)
77 unsigned char channel;
79 unsigned char options;
81 unsigned char essid[32];
85 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x03, 0x01,
89 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x07, 0x01,
93 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x07, 0x02,
96 char operAccessPointName[] =
97 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x0A,
101 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x05, 0x01,
105 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x07,
108 char bridgeOperationalMode[] =
109 { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01,
110 0x01, 0x04, 0x01, 0x00
113 struct EthernetRxStatistics *EthRxStat = NULL;
114 struct EthernetTxStatistics *EthTxStat = NULL;
115 struct WirelessStatistics *WirelessStat = NULL;
118 char message[12], bssid_flag, stat_type = 0, *ERR_STR =
119 ERR_STR_N, *bssid = NULL, *name = NULL;
120 struct sockaddr_in client;
123 setlocale(LC_ALL, "");
124 bindtextdomain("ap-utils", LOCALEDIR);
125 textdomain("ap-utils");
128 memset(&client, 0, sizeof client);
129 client.sin_family = AF_INET;
130 client.sin_port = INADDR_ANY;
131 client.sin_addr.s_addr = INADDR_ANY;
140 switch (opt = getopt(argc, argv, "i:c:t:b:n:a:rv")) {
142 if (inet_aton(optarg, &ap_ip) == 0) {
143 printf(_("Invalid IP-address\n"));
148 stat_type = optarg[0];
154 community = malloc(strlen(optarg) + 1);
155 strncpy(community, optarg, strlen(optarg) + 1);
158 bssid = malloc(strlen(optarg) + 1);
159 strncpy(bssid, optarg, strlen(optarg) + 1);
162 name = malloc(strlen(optarg) + 1);
163 strncpy(name, optarg, strlen(optarg) + 1);
169 if ( strcmp( optarg, "510\0" ) == 0) {
176 operAccessPointName[5] = 0xE0;
177 operAccessPointName[6] = 0x3E;
182 bridgeOperationalMode[5] = 0xE0;
183 bridgeOperationalMode[6] = 0x3E;
184 } else if (strcmp(optarg, "410") == 0) {
185 /* nothing - hard-coded defaults are fine */
187 /* Invalid AP-Type */
188 printf(_("Invalid AP-Type '%s' - valid types are 510 or 410\n"), optarg);
206 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
207 perror(_("Create socket error"));
210 if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1) {
211 perror(_("Bind socket error"));
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;
230 if (snmp(varbinds, 2, GET) <= 0) {
235 if (varbinds[0].len_val == 64) {
239 (struct EthernetRxStatistics *) malloc(varbinds[0].
241 memcpy(EthRxStat, varbinds[0].value, varbinds[0].len_val);
247 if (varbinds[1].len_val == 56) {
251 (struct EthernetTxStatistics *) malloc(varbinds[1].
253 memcpy(EthTxStat, varbinds[1].value, varbinds[1].len_val);
258 printf("%u\n%u\n", swap4(EthRxStat->TotalBytesRx),
259 swap4(EthTxStat->TotalBytesTx));
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;
272 if (snmp(varbinds, 1, GET) <= 0) {
277 if (varbinds[0].len_val == 88) {
281 (struct WirelessStatistics *) malloc(varbinds[0].len_val);
282 memcpy(WirelessStat, varbinds[0].value, varbinds[0].len_val);
288 swap4(WirelessStat->UnicastReceivedPackets) +
289 swap4(WirelessStat->BroadcastReceivedPackets) +
290 swap4(WirelessStat->MulticastReceivedPackets),
291 swap4(WirelessStat->UnicastTransmittedPackets) +
292 swap4(WirelessStat->BroadcastTransmittedPackets) +
293 swap4(WirelessStat->MulticastTransmittedPackets));
297 varbinds[0].oid = StasNum;
298 varbinds[0].len_oid = sizeof(StasNum);
299 varbinds[0].value = StasNum;
300 varbinds[0].len_val = 0;
301 varbinds[0].type = NULL_VALUE;
303 if (snmp(varbinds, 1, GET) <= 0) {
308 printf("%u\n0\n", *varbinds[0].value);
313 varbinds[0].oid = bridgeOperationalMode;
314 varbinds[0].len_oid = sizeof(bridgeOperationalMode);
315 varbinds[0].len_val = 0;
316 varbinds[0].type = NULL_VALUE;
318 if (snmp(varbinds, 1, GET) <= 0) {
323 if (*(varbinds[0].value) != 3) {
336 varbinds[0].oid = KnownAP;
337 varbinds[0].len_oid = sizeof(KnownAP);
338 varbinds[0].type = NULL_VALUE;
339 varbinds[0].len_val = 0;
341 if (snmp(varbinds, 1, GET) <= 0) {
346 for (i = 0; i < varbinds[0].len_val; i += 48) {
349 app = (struct ap *) malloc(48);
350 memcpy(app, varbinds[0].value + i, 48);
354 sprintf(message, "%02X%02X%02X%02X%02X%02X",
355 app->mac[0] & 0xFF, app->mac[1] & 0xFF,
356 app->mac[2] & 0xFF, app->mac[3] & 0xFF,
357 app->mac[4] & 0xFF, app->mac[5] & 0xFF);
358 if (memcmp(message, bssid, 12))
361 printf("%d\n%d\n", app->q2,
377 if ( name != NULL ) {
378 varbinds[0].oid = operAccessPointName;
379 varbinds[0].len_oid = sizeof(operAccessPointName);
380 varbinds[0].len_val = 0;
381 varbinds[0].type = NULL_VALUE;
382 if (snmp(varbinds, 1, GET) <= 0) {
387 for (i = 0; i < 32 && *(varbinds[0].value + i); i++)
388 putchar(*(varbinds[0].value + i));
390 if (strncmp(name,varbinds[0].value,strlen(name)) ){