--- /dev/null
+/*
+ * ap-auth.c from Access Point SNMP Utils for Linux
+ *
+ * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 from
+ * June 1991 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#if defined (__GLIBC__)
+#include <libgen.h>
+#endif
+#include "ap-utils.h"
+
+#define PACKET_ERROR _("AuthorizedMacTableString packet error")
+#define ERROR_DATA _("Invalid data in source file")
+#define ERROR_FILE_OPEN _("Can't open file")
+#define ERROR_FILE_WRITE _("Can't write to file")
+#define ERROR_FILE_CLOSE _("Error closing file")
+
+short ap_type = ATMEL410;
+char *community = NULL;
+int sockfd;
+struct in_addr ap_ip;
+
+void usage()
+{
+ printf(_("\nUsage:\n"));
+ printf(_("\tap-auth -i ip -c community -d filename [-h]\n"));
+ printf(_("\tap-auth -i ip -c community -u filename [-h]\n\n"));
+ printf(_("Change accesspoint's list of authorised MAC"
+ " addresses\n\n"));
+ printf(_("-i ip - AP ip address\n"));
+ printf(_("-c community - SNMP community string\n"));
+ printf(_("-d filename - download list of authorised MAC addresses from AP"
+ " to a file\n"));
+ printf(_("-u filename - upload list of authorised MAC addresses from"
+ " a file to AP\n"));
+ printf(_("-h - print this help screen\n\n"));
+ printf(_("ap-auth %s Copyright (c) 2002-2004 Roman Festchook\n\n"),
+ VERSION);
+}
+
+int write_addr (FILE *f, const struct MacListStat *n)
+{
+ if (fprintf (f, "%02x%02x%02x%02x%02x%02x\n", n->addr[0], n->addr[1],
+ n->addr[2], n->addr[3],
+ n->addr[4], n->addr[5])
+ != 13)
+ return 1;
+
+ return 0;
+}
+
+int get_addr (struct MacListStat *ml, char *addr)
+{
+ int i;
+ char tmp[3];
+
+ if (strlen (addr) != 12)
+ return 1;
+
+ tmp[2] = '\0';
+
+ for (i = 0; i < 6 ; i++) {
+ tmp[0] = addr[2 * i];
+ tmp[1] = addr[2 * i + 1];
+ ml->addr[i] = strtol (tmp, NULL, 16);
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ extern char *optarg;
+ extern int optind;
+ extern int opterr;
+ extern int optopt;
+ int opt = 0;
+ int mode = 0; /* 1 = download, 2 = upload */
+
+ FILE *f;
+ char *filename = NULL;
+ struct sockaddr_in client;
+
+ struct AuthorizedMacTableString {
+ unsigned int short Action;
+ unsigned int short NumOfAllTableAddresses;
+ unsigned int short NumOfCurrentAddress;
+ unsigned char MacAddress[6];
+ } *AuthMac = NULL, get;
+
+ struct MacListStat *first = NULL, *curr = NULL;
+
+ char AutorizedMac[] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01,
+ 0x02, 0x06, 0x02, 0x00
+ };
+
+ int total_mac, mac_num = 0;
+ varbind varbinds[1];
+ char mac_tmp[13];
+ struct MacListStat ml_tmp;
+ int i, tmp;
+
+#ifdef HAVE_GETTEXT
+ setlocale(LC_ALL, "");
+ bindtextdomain("ap-utils", LOCALEDIR);
+ textdomain("ap-utils");
+#endif
+
+ memset(&client, 0, sizeof client);
+ client.sin_family = AF_INET;
+ client.sin_port = INADDR_ANY;
+ client.sin_addr.s_addr = INADDR_ANY;
+
+ do {
+ opterr = 0;
+ switch (opt = getopt(argc, argv, "i:c:d:u:")) {
+ case 'i':
+ if (inet_aton(optarg, &ap_ip) == 0) {
+ printf(_("Invalid IP-address\n"));
+ return 1;
+ }
+ break;
+ case 'c':
+ community = malloc(strlen(optarg) + 1);
+ strncpy(community, optarg, strlen(optarg) + 1);
+ break;
+ case 'd':
+ filename = malloc(strlen(optarg) + 1);
+ strncpy(filename, optarg, strlen(optarg) + 1);
+ mode = 1;
+ break;
+ case 'u':
+ filename = malloc(strlen(optarg) + 1);
+ strncpy(filename, optarg, strlen(optarg) + 1);
+ mode = 2;
+ break;
+ case -1:
+ break;
+ default:
+ usage();
+ return 1;
+ }
+ } while (opt != -1);
+
+ if (!community) {
+ usage();
+ return 1;
+ }
+
+ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+ perror(_("Create socket error"));
+ return 1;
+ }
+ if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1) {
+ perror(_("Bind socket error"));
+ return 1;
+ }
+
+ switch (mode) {
+
+ case 1: /* download */
+
+ total_mac = 0;
+ mac_num = 0;
+
+ while (mac_num <= total_mac) {
+ get.Action = 0x02; rshort(get.Action);
+ get.NumOfAllTableAddresses = total_mac; rshort(get.NumOfAllTableAddresses);
+ get.NumOfCurrentAddress = mac_num; rshort(get.NumOfCurrentAddress);
+
+ varbinds[0].oid = AutorizedMac;
+ varbinds[0].len_oid = sizeof(AutorizedMac);
+ varbinds[0].value = (char *) &get;
+ varbinds[0].len_val = 12;
+ varbinds[0].type = STRING_VALUE;
+
+ if (snmp(varbinds, 1, SET) <= 0) {
+ printf(ERR_RET);
+ printf("\n");
+ return 1;
+ }
+
+ if (varbinds[0].len_val == 12) {
+ if (AuthMac)
+ free(AuthMac);
+ AuthMac =
+ (struct AuthorizedMacTableString *) malloc(varbinds[0].
+ len_val);
+ memcpy(AuthMac, varbinds[0].value, varbinds[0].len_val);
+ } else {
+ printf(PACKET_ERROR);
+ printf("\n");
+ return 1;
+ }
+
+ rshort(AuthMac->NumOfAllTableAddresses);
+ total_mac =
+ (AuthMac->NumOfAllTableAddresses ==
+ 65535) ? 0 : AuthMac->NumOfAllTableAddresses;
+
+ if (mac_num) {
+ if (first == NULL) {
+ first = (struct MacListStat *)
+ malloc(sizeof(struct MacListStat));
+ curr = first;
+ } else {
+ curr->next = (struct MacListStat *)
+ malloc(sizeof(struct MacListStat));
+ curr = curr->next;
+ }
+ memcpy(curr->addr, AuthMac->MacAddress, 6);
+ curr->next = NULL;
+ }
+ mac_num++;
+ }
+ f = fopen(filename, "w");
+ if(f == NULL) {
+ perror(ERROR_FILE_OPEN);
+ return 1;
+ }
+ if (first == NULL) {
+ /* no authorised addresses */
+ } else {
+ curr = first;
+ while (curr != NULL) {
+ if(write_addr (f, curr) != 0) {
+ perror(ERROR_FILE_WRITE);
+ return 1;
+ }
+ curr = curr->next;
+ }
+ }
+ if(fclose(f) != 0) {
+ perror(ERROR_FILE_CLOSE);
+ return 1;
+ }
+ break;
+ case 2: /* upload */
+ f = fopen(filename, "r");
+ if (f == NULL) {
+ perror(ERROR_FILE_OPEN);
+ return 1;
+ }
+ mac_num = 0;
+ while (!feof (f)) {
+ tmp = fread (mac_tmp, 1, sizeof (mac_tmp), f);
+
+ if (tmp == sizeof (mac_tmp)) {
+ if (mac_tmp[12] != '\n') {
+ printf(ERROR_DATA);
+ printf("\n");
+ return 1;
+ }
+ mac_tmp[12] = '\0';
+
+ if (get_addr (&ml_tmp, mac_tmp) != 0) {
+ printf(ERROR_DATA);
+ printf("\n");
+ return 1;
+ }
+ if (first == NULL) {
+ first = (struct MacListStat *)
+ malloc (sizeof (struct MacListStat));
+ curr = first;
+ } else {
+ curr->next = (struct MacListStat *)
+ malloc (sizeof (struct MacListStat));
+ curr = curr->next;
+ }
+ memcpy (curr, &ml_tmp, sizeof (struct MacListStat));
+ curr->next = NULL;
+ mac_num++;
+ }
+ }
+ fclose(f);
+
+ curr = first;
+ i = 1;
+ while (curr != NULL) {
+ get.Action = 0x01;
+ rshort(get.Action);
+ get.NumOfAllTableAddresses = mac_num;
+ rshort(get.NumOfAllTableAddresses);
+ get.NumOfCurrentAddress = i;
+ rshort(get.NumOfCurrentAddress);
+ memcpy(get.MacAddress, curr->addr, 6);
+ varbinds[0].oid = AutorizedMac;
+ varbinds[0].len_oid = sizeof(AutorizedMac);
+ varbinds[0].value = (char *) &get;
+ varbinds[0].len_val = 12;
+ varbinds[0].type = STRING_VALUE;
+ if (snmp(varbinds, 1, SET) <= 0) {
+ printf(ERR_RET);
+ printf("\n");
+ return 1;
+ }
+ if (varbinds[0].len_val != 12) {
+ printf(PACKET_ERROR);
+ printf("\n");
+ return 1;
+ }
+ curr = curr->next;
+ i++;
+ }
+ break;
+ default:
+ usage();
+ return 1;
+ }
+
+ close(sockfd);
+
+ curr = first;
+ while (curr != NULL) {
+ curr = curr->next;
+ free (first);
+ first = curr;
+ }
+
+ if (community)
+ free(community);
+ if (filename)
+ free(filename);
+ return 0;
+}