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>