2 * ap-auth.c from Access Point SNMP Utils for Linux
4 * Copyright (c) 2004 Teemu Kiviniemi <teemuki at fotokone.fi>
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 ERROR_PACKET _("AuthorizedMacTableString packet error")
33 #define ERROR_DATA _("Invalid data in source file")
34 #define ERROR_FILE_OPEN _("Can't open file")
35 #define ERROR_FILE_WRITE _("Can't write to file")
36 #define ERROR_FILE_CLOSE _("Error closing file")
39 char *community = NULL;
45 printf(_("\nUsage:\n"));
46 printf(_("\tap-auth -i ip -c community -d filename [-h]\n"));
47 printf(_("\tap-auth -i ip -c community -u filename [-h]\n\n"));
48 printf(_("Change accesspoint's list of authorised MAC addresses\n\n"));
49 printf(_("-i ip - AP ip address\n"));
50 printf(_("-c community - SNMP community string\n"));
51 printf(_("-d filename - download list of authorised MAC addresses from AP"
53 printf(_("-u filename - upload list of authorised MAC addresses from"
55 printf(_("-h - print this help screen\n\n"));
56 printf(_("ap-auth %s Copyright (c) 2004 Teemu Kiviniemi\n\n"),
60 int write_addr (FILE *f, const struct MacListStat *n)
62 if (fprintf (f, "%02x%02x%02x%02x%02x%02x\n", n->addr[0], n->addr[1],
63 n->addr[2], n->addr[3],
64 n->addr[4], n->addr[5])
71 int get_addr (struct MacListStat *ml, char *addr)
76 if (strlen (addr) != 12)
81 for (i = 0; i < 6 ; i++) {
83 tmp[1] = addr[2 * i + 1];
84 ml->addr[i] = strtol (tmp, NULL, 16);
90 int main(int argc, char **argv)
97 int mode = 0; /* 1 = download, 2 = upload */
100 char *filename = NULL;
101 struct sockaddr_in client;
103 struct AuthorizedMacTableString {
104 unsigned int short Action;
105 unsigned int short NumOfAllTableAddresses;
106 unsigned int short NumOfCurrentAddress;
107 unsigned char MacAddress[6];
108 } *AuthMac = NULL, get;
110 struct MacListStat *first = NULL, *curr = NULL;
112 char sysDescr_NWN[] = {
113 0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00
115 char sysDescr_ATMEL[] = {
116 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x01, 0x00
118 char AutorizedMac_ATMEL[] = {
119 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x02, 0x00
122 int total_mac, mac_num = 0;
126 struct MacListStat ml_tmp;
130 setlocale(LC_ALL, "");
131 bindtextdomain("ap-utils", LOCALEDIR);
132 textdomain("ap-utils");
135 memset(&client, 0, sizeof client);
136 client.sin_family = AF_INET;
137 client.sin_port = INADDR_ANY;
138 client.sin_addr.s_addr = INADDR_ANY;
142 switch (opt = getopt(argc, argv, "i:c:d:u:")) {
144 for (cp = optarg, i = 0; *cp && (cp = index(cp, '.')); cp++, i++);
145 if (i < 3 || inet_aton(optarg, &ap_ip) == 0) {
146 printf(_("Error: invalid IP-address.\n"));
151 community = malloc(strlen(optarg) + 1);
152 strncpy(community, optarg, strlen(optarg) + 1);
155 filename = malloc(strlen(optarg) + 1);
156 strncpy(filename, optarg, strlen(optarg) + 1);
160 filename = malloc(strlen(optarg) + 1);
161 strncpy(filename, optarg, strlen(optarg) + 1);
177 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
178 perror(_("Create socket error"));
181 if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1) {
182 perror(_("Bind socket error"));
187 * Part detecting ap_type (ATMEL AP MIB type) follows.
188 * We could use get_mib_details() here with advantage, but it would
189 * have to involve 1. putting it to separate file in lib/ and
190 * 2. patch it so it would not contain curses-related commands (TODO)
193 /* determine private MIB type according to enterprises ID */
194 varbinds[0].oid = sysDescr_NWN;
195 varbinds[0].len_oid = sizeof(sysDescr_NWN);
196 varbinds[0].value = NULL;
197 varbinds[0].len_val = 0;
198 varbinds[0].type = NULL_VALUE;
199 if (snmp(varbinds, 1, GET) > 0) {
202 varbinds[0].oid = sysDescr_ATMEL;
203 varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
204 varbinds[0].value = NULL;
205 varbinds[0].len_val = 0;
206 varbinds[0].type = NULL_VALUE;
207 if (snmp(varbinds, 1, GET) > 0) {
210 sysDescr_ATMEL[5] = 0xE0;
211 sysDescr_ATMEL[6] = 0x3E;
212 varbinds[0].oid = sysDescr_ATMEL;
213 varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
214 varbinds[0].value = NULL;
215 varbinds[0].len_val = 0;
216 varbinds[0].type = NULL_VALUE;
217 if (snmp(varbinds, 1, GET) > 0) {
218 ap_type = ATMEL12350;
220 printf(_("Unable to determine AP MIB type "
221 "(no response from AP)."));
227 if (ap_type == NWN) {
228 printf(_("NWN devices are not yet supported."));
232 if (ap_type == ATMEL12350) {
233 AutorizedMac_ATMEL[5] = 0xE0;
234 AutorizedMac_ATMEL[6] = 0x3E;
239 case 1: /* download */
244 while (mac_num <= total_mac) {
245 get.Action = 0x02; rshort(get.Action);
246 get.NumOfAllTableAddresses = total_mac; rshort(get.NumOfAllTableAddresses);
247 get.NumOfCurrentAddress = mac_num; rshort(get.NumOfCurrentAddress);
249 varbinds[0].oid = AutorizedMac_ATMEL;
250 varbinds[0].len_oid = sizeof(AutorizedMac_ATMEL);
251 varbinds[0].value = (char *) &get;
252 varbinds[0].len_val = 12;
253 varbinds[0].type = STRING_VALUE;
255 if (snmp(varbinds, 1, SET) <= 0) {
261 if (varbinds[0].len_val == 12) {
265 (struct AuthorizedMacTableString *) malloc(varbinds[0].
267 memcpy(AuthMac, varbinds[0].value, varbinds[0].len_val);
269 printf(ERROR_PACKET);
274 rshort(AuthMac->NumOfAllTableAddresses);
276 (AuthMac->NumOfAllTableAddresses ==
277 65535) ? 0 : AuthMac->NumOfAllTableAddresses;
281 first = (struct MacListStat *)
282 malloc(sizeof(struct MacListStat));
285 curr->next = (struct MacListStat *)
286 malloc(sizeof(struct MacListStat));
289 memcpy(curr->addr, AuthMac->MacAddress, 6);
294 f = fopen(filename, "w");
296 perror(ERROR_FILE_OPEN);
300 /* no authorised addresses */
303 while (curr != NULL) {
304 if(write_addr (f, curr) != 0) {
305 perror(ERROR_FILE_WRITE);
312 perror(ERROR_FILE_CLOSE);
317 f = fopen(filename, "r");
319 perror(ERROR_FILE_OPEN);
324 tmp = fread (mac_tmp, 1, sizeof (mac_tmp), f);
326 if (tmp == sizeof (mac_tmp)) {
327 if (mac_tmp[12] != '\n') {
334 if (get_addr (&ml_tmp, mac_tmp) != 0) {
340 first = (struct MacListStat *)
341 malloc (sizeof (struct MacListStat));
344 curr->next = (struct MacListStat *)
345 malloc (sizeof (struct MacListStat));
348 memcpy (curr, &ml_tmp, sizeof (struct MacListStat));
357 while (curr != NULL) {
360 get.NumOfAllTableAddresses = mac_num;
361 rshort(get.NumOfAllTableAddresses);
362 get.NumOfCurrentAddress = i;
363 rshort(get.NumOfCurrentAddress);
364 memcpy(get.MacAddress, curr->addr, 6);
365 varbinds[0].oid = AutorizedMac_ATMEL;
366 varbinds[0].len_oid = sizeof(AutorizedMac_ATMEL);
367 varbinds[0].value = (char *) &get;
368 varbinds[0].len_val = 12;
369 varbinds[0].type = STRING_VALUE;
370 if (snmp(varbinds, 1, SET) <= 0) {
375 if (varbinds[0].len_val != 12) {
376 printf(ERROR_PACKET);
392 while (curr != NULL) {