Annotation of embedaddon/coova-chilli/src/main-query.c, revision 1.1
1.1 ! misho 1: /*
! 2: * chilli - ChilliSpot.org. A Wireless LAN Access Point Controller.
! 3: * Copyright (C) 2006 PicoPoint B.V.
! 4: * Copyright (c) 2006-2007 David Bird <david@coova.com>
! 5: *
! 6: * The contents of this file may be used under the terms of the GNU
! 7: * General Public License Version 2, provided that the above copyright
! 8: * notice and this permission notice is included in all copies or
! 9: * substantial portions of the software.
! 10: *
! 11: */
! 12:
! 13: #include "system.h"
! 14: #include "syserr.h"
! 15: #include "cmdline.h"
! 16: #include "dhcp.h"
! 17: #include "radius.h"
! 18: #include "radius_chillispot.h"
! 19: #include "radius_wispr.h"
! 20: #include "redir.h"
! 21: #include "chilli.h"
! 22: #include "options.h"
! 23: #include "cmdsock.h"
! 24:
! 25: static int usage(char *program) {
! 26: fprintf(stderr, "Usage: %s [ -s <socket> ] <command> [<argument>]\n", program);
! 27: fprintf(stderr, " socket = full path to UNIX domain socket (e.g. /var/run/chilli.sock)\n");
! 28: /* fprintf(stderr, " TCP socket port, or ip:port, to bind to (e.g. 1999)\n"); */
! 29: return 1;
! 30: }
! 31:
! 32: typedef struct _cmd_info {
! 33: int type;
! 34: char *command;
! 35: char *desc;
! 36: } cmd_info;
! 37:
! 38: static cmd_info commands[] = {
! 39: { CMDSOCK_LIST, "list", NULL },
! 40: { CMDSOCK_ROUTE, "route", NULL },
! 41: { CMDSOCK_DHCP_LIST, "dhcp-list", NULL },
! 42: { CMDSOCK_DHCP_RELEASE, "dhcp-release", NULL },
! 43: { CMDSOCK_AUTHORIZE, "authorize", NULL },
! 44: { CMDSOCK_DHCP_RELEASE, "logout", NULL },
! 45: { CMDSOCK_DHCP_RELEASE, "logoff", NULL },
! 46: { CMDSOCK_DHCP_DROP, "drop", NULL },
! 47: { CMDSOCK_DHCP_DROP, "block", NULL },
! 48: { 0, NULL, NULL }
! 49: };
! 50:
! 51: int main(int argc, char **argv) {
! 52: /*
! 53: * chilli_query [ -s <unix-socket> ] <command> [<argument>]
! 54: * (or maybe this should get the unix-socket from the config file)
! 55: */
! 56:
! 57: char *cmdsock = DEFCMDSOCK;
! 58: int s, len;
! 59: struct sockaddr_un remote;
! 60: struct cmdsock_request request;
! 61: char line[1024], *cmd;
! 62: int argidx = 1;
! 63:
! 64: if (argc < 2) return usage(argv[0]);
! 65:
! 66: if (*argv[argidx] == '/') {
! 67: /* for backward support, ignore a unix-socket given as first arg */
! 68: if (argc < 3) return usage(argv[0]);
! 69: cmdsock = argv[argidx++];
! 70: }
! 71:
! 72: memset(&request,0,sizeof(request));
! 73:
! 74: while (argidx < argc && *argv[argidx] == '-') {
! 75: if (!strcmp(argv[argidx], "-s")) {
! 76: argidx++;
! 77: if (argidx >= argc) return usage(argv[0]);
! 78: cmdsock = argv[argidx++];
! 79: } else if (!strcmp(argv[argidx], "-json")) {
! 80: request.options |= CMDSOCK_OPT_JSON;
! 81: argidx++;
! 82: }
! 83: }
! 84:
! 85: if (argidx >= argc) return usage(argv[0]);
! 86:
! 87: cmd = argv[argidx++];
! 88: for (s = 0; commands[s].command; s++) {
! 89: if (!strcmp(cmd, commands[s].command)) {
! 90: request.type = commands[s].type;
! 91: switch(request.type) {
! 92: case CMDSOCK_AUTHORIZE:
! 93: {
! 94: struct arguments {
! 95: char *name;
! 96: int type; /* 0=string, 1=integer, 2=ip */
! 97: int length;
! 98: void *field;
! 99: char *desc;
! 100: char *flag;
! 101: char flagbit;
! 102: } args[] = {
! 103: { "ip", 2,
! 104: sizeof(request.data.sess.ip),
! 105: &request.data.sess.ip,
! 106: "IP of client to authorize",0,0 },
! 107: { "sessionid", 0,
! 108: sizeof(request.data.sess.sessionid),
! 109: request.data.sess.sessionid,
! 110: "Session-id to authorize",0,0 },
! 111: { "username", 0,
! 112: sizeof(request.data.sess.username),
! 113: request.data.sess.username,
! 114: "Username to use in RADIUS Accounting",0,0 },
! 115: { "sessiontimeout", 1,
! 116: sizeof(request.data.sess.params.sessiontimeout),
! 117: &request.data.sess.params.sessiontimeout,
! 118: "Max session time (in seconds)",0,0 },
! 119: { "maxoctets", 1,
! 120: sizeof(request.data.sess.params.maxtotaloctets),
! 121: &request.data.sess.params.maxtotaloctets,
! 122: "Max up/down octets (bytes)",0,0 },
! 123: { "maxbwup", 1,
! 124: sizeof(request.data.sess.params.bandwidthmaxup),
! 125: &request.data.sess.params.bandwidthmaxup,
! 126: "Max bandwidth up",0,0 },
! 127: { "maxbwdown", 1,
! 128: sizeof(request.data.sess.params.bandwidthmaxdown),
! 129: &request.data.sess.params.bandwidthmaxdown,
! 130: "Max bandwidth down",0,0 },
! 131: { "splash", 0,
! 132: sizeof(request.data.sess.params.url),
! 133: &request.data.sess.params.url,
! 134: "Set splash page",
! 135: &request.data.sess.params.flags, REQUIRE_UAM_SPLASH },
! 136: { "routeidx", 1,
! 137: sizeof(request.data.sess.params.routeidx),
! 138: &request.data.sess.params.routeidx,
! 139: "Route interface index", 0, 0 },
! 140: /* more... */
! 141: };
! 142: int count = sizeof(args)/sizeof(struct arguments);
! 143: int pos = argidx;
! 144: argc -= argidx;
! 145: while(argc > 0) {
! 146: int i;
! 147:
! 148: for (i=0; i<count; i++) {
! 149:
! 150: if (!strcmp(argv[pos],args[i].name)) {
! 151:
! 152: if (argc == 1) {
! 153: fprintf(stderr, "Argument %s requires a value\n", argv[pos]);
! 154: return usage(argv[0]);
! 155: }
! 156:
! 157: if (args[i].flag) {
! 158: *(args[i].flag) |=args[i].flagbit;
! 159: }
! 160:
! 161: switch(args[i].type) {
! 162: case 0:
! 163: strncpy(((char *)args[i].field), argv[pos+1], args[i].length-1);
! 164: break;
! 165: case 1:
! 166: switch(args[i].length) {
! 167: case 1:
! 168: *((uint8_t *)args[i].field) = (uint8_t)atoi(argv[pos+1]);
! 169: break;
! 170: case 2:
! 171: *((uint16_t *)args[i].field) = (uint16_t)atoi(argv[pos+1]);
! 172: break;
! 173: case 4:
! 174: *((uint32_t *)args[i].field) = (uint32_t)atoi(argv[pos+1]);
! 175: break;
! 176: }
! 177: break;
! 178: case 2:
! 179: if (!inet_aton(argv[pos+1], ((struct in_addr *)args[i].field))) {
! 180: fprintf(stderr, "Invalid IP Address: %s\n", argv[pos+1]);
! 181: return usage(argv[0]);
! 182: }
! 183: break;
! 184: }
! 185: break;
! 186: }
! 187: }
! 188:
! 189: if (i == count) {
! 190: fprintf(stderr, "Unknown argument: %s\n", argv[pos]);
! 191: fprintf(stderr, "Use:\n");
! 192: for (i=0; i<count; i++) {
! 193: fprintf(stderr, " %-15s<value> - type: %-6s - %s\n",
! 194: args[i].name,
! 195: args[i].type == 0 ? "string" :
! 196: args[i].type == 1 ? "long" :
! 197: args[i].type == 2 ? "int" :
! 198: args[i].type == 3 ? "ip" :
! 199: "unknown", args[i].desc);
! 200: }
! 201: fprintf(stderr, "The ip and/or sessionid is required.\n");
! 202: return usage(argv[0]);
! 203: }
! 204:
! 205: argc -= 2;
! 206: pos += 2;
! 207: }
! 208: }
! 209: break;
! 210: case CMDSOCK_DHCP_DROP:
! 211: case CMDSOCK_DHCP_RELEASE:
! 212: {
! 213: unsigned int temp[PKT_ETH_ALEN];
! 214: char macstr[RADIUS_ATTR_VLEN];
! 215: int macstrlen;
! 216: int i;
! 217:
! 218: if (argc < argidx+1) {
! 219: fprintf(stderr, "%s requires a MAC address argument\n", cmd);
! 220: return usage(argv[0]);
! 221: }
! 222:
! 223: if ((macstrlen = strlen(argv[argidx])) >= (RADIUS_ATTR_VLEN-1)) {
! 224: fprintf(stderr, "%s: bad MAC address\n", argv[argidx]);
! 225: return -1;
! 226: }
! 227:
! 228: memcpy(macstr, argv[argidx], macstrlen);
! 229: macstr[macstrlen] = 0;
! 230:
! 231: for (i=0; i<macstrlen; i++)
! 232: if (!isxdigit(macstr[i]))
! 233: macstr[i] = 0x20;
! 234:
! 235: if (sscanf(macstr, "%2x %2x %2x %2x %2x %2x",
! 236: &temp[0], &temp[1], &temp[2],
! 237: &temp[3], &temp[4], &temp[5]) != 6) {
! 238: fprintf(stderr, "%s: bad MAC address\n", argv[argidx]);
! 239: return -1;
! 240: }
! 241:
! 242: for (i = 0; i < PKT_ETH_ALEN; i++)
! 243: request.data.mac[i] = temp[i];
! 244:
! 245: /* do another switch to pick up param configs for authorize */
! 246: }
! 247: break;
! 248: case CMDSOCK_ROUTE:
! 249: {
! 250: unsigned int temp[PKT_ETH_ALEN];
! 251: char macstr[RADIUS_ATTR_VLEN];
! 252: int macstrlen;
! 253: int routeidx;
! 254: int i;
! 255:
! 256: if (argc < argidx + 2) {
! 257: break;
! 258: }
! 259:
! 260: if ((macstrlen = strlen(argv[argidx])) >= (RADIUS_ATTR_VLEN-1)) {
! 261: fprintf(stderr, "%s: bad MAC address\n", argv[argidx]);
! 262: break;
! 263: }
! 264:
! 265: memcpy(macstr, argv[argidx], macstrlen);
! 266: macstr[macstrlen] = 0;
! 267:
! 268: for (i=0; i<macstrlen; i++)
! 269: if (!isxdigit(macstr[i]))
! 270: macstr[i] = 0x20;
! 271:
! 272: if (sscanf(macstr, "%2x %2x %2x %2x %2x %2x",
! 273: &temp[0], &temp[1], &temp[2],
! 274: &temp[3], &temp[4], &temp[5]) != 6) {
! 275: fprintf(stderr, "%s: bad MAC address\n", argv[argidx]);
! 276: break;
! 277: }
! 278:
! 279: for (i = 0; i < PKT_ETH_ALEN; i++)
! 280: request.data.mac[i] = temp[i];
! 281:
! 282: argidx++;
! 283: request.data.sess.params.routeidx = atoi(argv[argidx]);
! 284:
! 285: request.type = CMDSOCK_ROUTE_SET;
! 286:
! 287: /* do another switch to pick up param configs for authorize */
! 288: }
! 289: break;
! 290: }
! 291: break;
! 292: }
! 293: }
! 294:
! 295: if (!commands[s].command) {
! 296: fprintf(stderr,"unknown command: %s\n",cmd);
! 297: exit(1);
! 298: }
! 299:
! 300: if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
! 301: perror("socket");
! 302: exit(1);
! 303: }
! 304:
! 305: remote.sun_family = AF_UNIX;
! 306: strcpy(remote.sun_path, cmdsock);
! 307: len = strlen(remote.sun_path) + sizeof(remote.sun_family);
! 308: if (connect(s, (struct sockaddr *)&remote, len) == -1) {
! 309: perror("connect");
! 310: exit(1);
! 311: }
! 312:
! 313: if (write(s, &request, sizeof(request)) != sizeof(request)) {
! 314: perror("write");
! 315: exit(1);
! 316: }
! 317:
! 318: while((len = read(s, line, sizeof(line)-1)) > 0)
! 319: write(1, line, len);
! 320:
! 321: if (len < 0)
! 322: perror("read");
! 323:
! 324: shutdown(s,2);
! 325: close(s);
! 326:
! 327: return 0;
! 328: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>