Annotation of embedaddon/coova-chilli/src/main-query.c, revision 1.1.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>