Annotation of embedaddon/mpd/src/web.c, revision 1.1.1.2
1.1 misho 1:
2: /*
3: * web.c
4: *
5: * Written by Alexander Motin <mav@FreeBSD.org>
6: */
7:
8: #include "ppp.h"
9: #include "web.h"
10: #include "util.h"
11:
12:
13: /*
14: * DEFINITIONS
15: */
16:
17: /* Set menu options */
18: enum {
19: SET_OPEN,
20: SET_CLOSE,
21: SET_SELF,
22: SET_DISABLE,
23: SET_ENABLE
24: };
25:
26:
27: /*
28: * INTERNAL FUNCTIONS
29: */
30:
31: static int WebSetCommand(Context ctx, int ac, char *av[], void *arg);
32:
33: static int WebServletRun(struct http_servlet *servlet,
34: struct http_request *req, struct http_response *resp);
35: static void WebServletDestroy(struct http_servlet *servlet);
36:
37: static void WebLogger(int sev, const char *fmt, ...);
38:
39: static void WebConsoleSessionWrite(ConsoleSession cs, const char *fmt, ...);
40: static void WebConsoleSessionWriteV(ConsoleSession cs, const char *fmt, va_list vl);
41: static void WebConsoleSessionShowPrompt(ConsoleSession cs);
42:
43: static void WebRunBinCmd(FILE *f, const char *query, int priv);
44: static void WebRunCmd(FILE *f, const char *query, int priv);
1.1.1.2 ! misho 45: static void WebShowHTMLSummary(FILE *f, int priv);
! 46: static void WebShowJSONSummary(FILE *f, int priv);
1.1 misho 47:
48: /*
49: * GLOBAL VARIABLES
50: */
51:
52: const struct cmdtab WebSetCmds[] = {
53: { "open", "Open the web" ,
54: WebSetCommand, NULL, 2, (void *) SET_OPEN },
55: { "close", "Close the web" ,
56: WebSetCommand, NULL, 2, (void *) SET_CLOSE },
57: { "self {ip} [{port}]", "Set web ip and port" ,
58: WebSetCommand, NULL, 2, (void *) SET_SELF },
59: { "enable [opt ...]", "Enable web option" ,
60: WebSetCommand, NULL, 2, (void *) SET_ENABLE },
61: { "disable [opt ...]", "Disable web option" ,
62: WebSetCommand, NULL, 2, (void *) SET_DISABLE },
63: { NULL },
64: };
65:
66:
67: /*
68: * INTERNAL VARIABLES
69: */
70:
71: static const struct confinfo gConfList[] = {
72: { 0, WEB_AUTH, "auth" },
73: { 0, 0, NULL },
74: };
75:
76: static struct pevent_ctx *gWebCtx = NULL;
77:
78: /*
79: * WebInit()
80: */
81:
82: int
83: WebInit(Web w)
84: {
85: /* setup web-defaults */
86: memset(w, 0, sizeof(*w));
87:
88: Enable(&w->options, WEB_AUTH);
89:
90: ParseAddr(DEFAULT_WEB_IP, &w->addr, ALLOW_IPV4|ALLOW_IPV6);
91: w->port = DEFAULT_WEB_PORT;
92:
93: return 0;
94: }
95:
96: /*
97: * WebOpen()
98: */
99:
100: int
101: WebOpen(Web w)
102: {
103: char addrstr[INET6_ADDRSTRLEN];
104:
105: if (w->srv) {
106: Log(LG_ERR, ("web: web already running"));
107: return -1;
108: }
109:
110: gWebCtx = pevent_ctx_create(MB_WEB, NULL);
111: if (!gWebCtx) {
112: Log(LG_ERR, ("%s: error pevent_ctx_create: %d", __FUNCTION__, errno));
113: return(-1);
114: }
115:
116: if (!(w->srv = http_server_start(gWebCtx, w->addr.u.ip4,
117: w->port, NULL, "mpd web server", WebLogger))) {
118: Log(LG_ERR, ("%s: error http_server_start: %d", __FUNCTION__, errno));
119: return(-1);
120: }
121:
122: w->srvlet.arg=NULL;
123: w->srvlet.hook=NULL;
124: w->srvlet.run=WebServletRun;
125: w->srvlet.destroy=WebServletDestroy;
126:
127: if (http_server_register_servlet(w->srv, &w->srvlet, NULL, ".*", 10) < 0) {
128: Log(LG_ERR, ("%s: error http_server_register_servlet: %d", __FUNCTION__, errno));
129: return(-1);
130: }
131:
132: Log(LG_ERR, ("web: listening on %s %d",
133: u_addrtoa(&w->addr,addrstr,sizeof(addrstr)), w->port));
134: return 0;
135: }
136:
137: /*
138: * WebClose()
139: */
140:
141: int
142: WebClose(Web w)
143: {
144: if (!w->srv) {
145: Log(LG_ERR, ("web: web is not running"));
146: return -1;
147: }
148:
149: http_server_stop(&w->srv);
150: if (gWebCtx) pevent_ctx_destroy(&gWebCtx);
151:
152: return 0;
153: }
154:
155: /*
156: * WebStat()
157: */
158:
159: int
160: WebStat(Context ctx, int ac, char *av[], void *arg)
161: {
162: Web w = &gWeb;
163: char addrstr[64];
164:
165: Printf("Web configuration:\r\n");
166: Printf("\tState : %s\r\n", w->srv ? "OPENED" : "CLOSED");
167: Printf("\tIP-Address : %s\r\n", u_addrtoa(&w->addr,addrstr,sizeof(addrstr)));
168: Printf("\tPort : %d\r\n", w->port);
169:
170: Printf("Web options:\r\n");
171: OptStat(ctx, &w->options, gConfList);
172:
173: return 0;
174: }
175:
176: /*
177: * ConsoleSessionWriteV()
178: */
179:
180: static void
181: WebConsoleSessionWriteV(ConsoleSession cs, const char *fmt, va_list vl)
182: {
183: vfprintf((FILE *)(cs->cookie), fmt, vl);
184: }
185:
186: /*
187: * WebConsoleSessionWrite()
188: */
189:
190: static void
191: WebConsoleSessionWrite(ConsoleSession cs, const char *fmt, ...)
192: {
193: va_list vl;
194:
195: va_start(vl, fmt);
196: WebConsoleSessionWriteV(cs, fmt, vl);
197: va_end(vl);
198: }
199:
200: /*
201: * WebConsoleShowPrompt()
202: */
203:
204: static void
205: WebConsoleSessionShowPrompt(ConsoleSession cs)
206: {
207: if (cs->context.lnk)
208: cs->write(cs, "[%s] ", cs->context.lnk->name);
209: else if (cs->context.bund)
210: cs->write(cs, "[%s] ", cs->context.bund->name);
211: else if (cs->context.rep)
212: cs->write(cs, "[%s] ", cs->context.rep->name);
213: else
214: cs->write(cs, "[] ");
215: }
216:
217: static void
218: WebShowCSS(FILE *f)
219: {
220: fprintf(f, "body {font-family: Arial, Helvetica, Sans-Serif; background-color: #EEEEEE; }\n");
1.1.1.2 ! misho 221: fprintf(f, "table, pre {background-color: #FFFFFF; }\n");
1.1 misho 222: fprintf(f, "th, td {padding: 0 2pt 0 2pt; }\n");
223: fprintf(f, "th {background-color: #00B000; }\n");
224: fprintf(f, "td {background-color: #EEEEEE; }\n");
225: fprintf(f, "td.r {background-color: #EECCCC; }\n");
226: fprintf(f, "td.y {background-color: #EEEEBB; }\n");
227: fprintf(f, "td.g {background-color: #BBEEBB; }\n");
228: fprintf(f, "td.d {background-color: #CCCCCC; }\n");
229: fprintf(f, "a, a:visited, a:link { color: blue; }\n");
230: }
231:
232: static void
1.1.1.2 ! misho 233: WebShowHTMLSummary(FILE *f, int priv)
1.1 misho 234: {
235: int b,l;
236: Bund B;
237: Link L;
238: Rep R;
239: char buf[64],buf2[64];
240:
1.1.1.2 ! misho 241: fprintf(f, "<h2>Current status summary</h2>\n");
1.1 misho 242: fprintf(f, "<table>\n");
1.1.1.2 ! misho 243: fprintf(f, "<thead>\n<tr>\n<th>Bund</th>\n<th colspan=\"2\">Iface</th>\n<th>IPCP</th>\n<th>IPV6CP</th>\n<th>CCP</th>\n<th>ECP</th>\n"
! 244: "<th>Link</th>\n<th>LCP</th>\n<th>User</th>\n<th colspan=\"2\">Device</th>\n<th>Peer</th>\n<th>IP</th>\n<th> </th>\n<th> </th>\n<th> </th>\n%s</tr>\n</thead>\n<tbody>\n",
! 245: priv?"<th>State</th>\n":"");
1.1 misho 246: #define FSM_COLOR(s) (((s)==ST_OPENED)?"g":(((s)==ST_INITIAL)?"r":"y"))
247: #define PHYS_COLOR(s) (((s)==PHYS_STATE_UP)?"g":(((s)==PHYS_STATE_DOWN)?"r":"y"))
248: for (b = 0; b<gNumLinks; b++) {
249: if ((L=gLinks[b]) != NULL && L->bund == NULL && L->rep == NULL) {
1.1.1.2 ! misho 250: fprintf(f, "<tr>\n");
! 251: fprintf(f, "<td colspan=\"7\"> </td>\n");
! 252: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20link\">%s</a></td>\n",
1.1 misho 253: L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->name);
1.1.1.2 ! misho 254: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20lcp\">%s</a></td>\n",
1.1 misho 255: L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, FsmStateName(L->lcp.fsm.state));
1.1.1.2 ! misho 256: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20auth\">%s</a></td>\n",
1.1 misho 257: L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->lcp.auth.params.authname);
1.1.1.2 ! misho 258: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20device\">%s</a></td>\n",
1.1 misho 259: L->tmpl?"d":PHYS_COLOR(L->state), L->name, L->type?L->type->name:"");
1.1.1.2 ! misho 260: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20device\">%s</a></td>\n",
1.1 misho 261: L->tmpl?"d":PHYS_COLOR(L->state), L->name, gPhysStateNames[L->state]);
262: if (L->state != PHYS_STATE_DOWN) {
263: PhysGetPeerAddr(L, buf, sizeof(buf));
1.1.1.2 ! misho 264: fprintf(f, "<td>%s</td>\n", buf);
! 265: fprintf(f, "<td> </td>\n");
1.1 misho 266: PhysGetCallingNum(L, buf, sizeof(buf));
267: PhysGetCalledNum(L, buf2, sizeof(buf2));
268: if (PhysGetOriginate(L) == LINK_ORIGINATE_REMOTE) {
1.1.1.2 ! misho 269: fprintf(f, "<td>%s</td>\n<td><=</td>\n<td>%s</td>\n",
1.1 misho 270: buf2, buf);
271: } else {
1.1.1.2 ! misho 272: fprintf(f, "<td>%s</td>\n<td>=></td>\n<td>%s</td>\n",
1.1 misho 273: buf, buf2);
274: }
275: } else {
1.1.1.2 ! misho 276: fprintf(f, "<td> </td>\n");
! 277: fprintf(f, "<td> </td>\n");
! 278: fprintf(f, "<td colspan=\"3\"> </td>\n");
1.1 misho 279: }
280: if (priv) {
281: if (!L->tmpl) {
282: switch (L->state) {
283: case PHYS_STATE_DOWN:
1.1.1.2 ! misho 284: fprintf(f, "<td><a href=\"/cmd?link%%20%s&open\">[Open]</a></td>\n",
1.1 misho 285: L->name);
286: break;
287: case PHYS_STATE_UP:
1.1.1.2 ! misho 288: fprintf(f, "<td><a href=\"/cmd?link%%20%s&close\">[Close]</a></td>\n",
1.1 misho 289: L->name);
290: break;
291: default:
1.1.1.2 ! misho 292: fprintf(f, "<td><a href=\"/cmd?link%%20%s&open\">[Open]</a> <a href=\"/cmd?link%%20%s&close\">[Close]</a></td>\n",
1.1 misho 293: L->name, L->name);
294: }
295: } else {
1.1.1.2 ! misho 296: fprintf(f, "<td> </td>\n");
1.1 misho 297: }
298: }
1.1.1.2 ! misho 299: fprintf(f, "</tr>\n");
1.1 misho 300: }
301: }
302: for (b = 0; b<gNumBundles; b++) {
303: if ((B=gBundles[b]) != NULL) {
304: int rows = B->n_links?B->n_links:1;
305: int first = 1;
1.1.1.2 ! misho 306: fprintf(f, "<tr>\n");
! 307: fprintf(f, "<td rowspan=\"%d\" class=\"%s\"><a href=\"/cmd?bund%%20%s&show%%20bund\">%s</a></td>\n",
1.1 misho 308: rows, B->tmpl?"d":(B->iface.up?"g":"r"), B->name, B->name);
1.1.1.2 ! misho 309: fprintf(f, "<td rowspan=\"%d\" class=\"%s\"><a href=\"/cmd?bund%%20%s&show%%20iface\">%s</a></td>\n",
1.1 misho 310: rows, B->tmpl?"d":(B->iface.up?"g":"r"), B->name, B->iface.ifname);
1.1.1.2 ! misho 311: fprintf(f, "<td rowspan=\"%d\" class=\"%s\"><a href=\"/cmd?bund%%20%s&show%%20iface\">%s</a></td>\n",
1.1 misho 312: rows, B->tmpl?"d":(B->iface.up?"g":"r"), B->name, (B->iface.up?"Up":"Down"));
1.1.1.2 ! misho 313: fprintf(f, "<td rowspan=\"%d\" class=\"%s\"><a href=\"/cmd?bund%%20%s&show%%20ipcp\">%s</a></td>\n",
1.1 misho 314: rows, B->tmpl?"d":FSM_COLOR(B->ipcp.fsm.state), B->name,FsmStateName(B->ipcp.fsm.state));
1.1.1.2 ! misho 315: fprintf(f, "<td rowspan=\"%d\" class=\"%s\"><a href=\"/cmd?bund%%20%s&show%%20ipv6cp\">%s</a></td>\n",
1.1 misho 316: rows, B->tmpl?"d":FSM_COLOR(B->ipv6cp.fsm.state), B->name,FsmStateName(B->ipv6cp.fsm.state));
1.1.1.2 ! misho 317: fprintf(f, "<td rowspan=\"%d\" class=\"%s\"><a href=\"/cmd?bund%%20%s&show%%20ccp\">%s</a></td>\n",
1.1 misho 318: rows, B->tmpl?"d":FSM_COLOR(B->ccp.fsm.state), B->name,FsmStateName(B->ccp.fsm.state));
1.1.1.2 ! misho 319: fprintf(f, "<td rowspan=\"%d\" class=\"%s\"><a href=\"/cmd?bund%%20%s&show%%20ecp\">%s</a></td>\n",
1.1 misho 320: rows, B->tmpl?"d":FSM_COLOR(B->ecp.fsm.state), B->name,FsmStateName(B->ecp.fsm.state));
321: if (B->n_links == 0) {
1.1.1.2 ! misho 322: fprintf(f, "<td colspan=\"11\"> </td>\n</tr>\n");
1.1 misho 323: }
324: for (l = 0; l < NG_PPP_MAX_LINKS; l++) {
325: if ((L=B->links[l]) != NULL) {
326: if (first)
327: first = 0;
328: else
1.1.1.2 ! misho 329: fprintf(f, "<tr>\n");
! 330: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20link\">%s</a></td>\n",
1.1 misho 331: L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->name);
1.1.1.2 ! misho 332: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20lcp\">%s</a></td>\n",
1.1 misho 333: L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, FsmStateName(L->lcp.fsm.state));
1.1.1.2 ! misho 334: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20auth\">%s</a></td>\n",
1.1 misho 335: L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->lcp.auth.params.authname);
1.1.1.2 ! misho 336: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20device\">%s</a></td>\n",
1.1 misho 337: L->tmpl?"d":PHYS_COLOR(L->state), L->name, L->type?L->type->name:"");
1.1.1.2 ! misho 338: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20device\">%s</a></td>\n",
1.1 misho 339: L->tmpl?"d":PHYS_COLOR(L->state), L->name, gPhysStateNames[L->state]);
340: if (L->state != PHYS_STATE_DOWN) {
341: PhysGetPeerAddr(L, buf, sizeof(buf));
1.1.1.2 ! misho 342: fprintf(f, "<td>%s</td>\n", buf);
1.1 misho 343: if (L->bund != NULL)
1.1.1.2 ! misho 344: fprintf(f, "<td>%s</td>\n", inet_ntoa(L->bund->ipcp.peer_addr));
1.1 misho 345: else
1.1.1.2 ! misho 346: fprintf(f, "<td> </td>\n");
1.1 misho 347: PhysGetCallingNum(L, buf, sizeof(buf));
348: PhysGetCalledNum(L, buf2, sizeof(buf2));
349: if (PhysGetOriginate(L) == LINK_ORIGINATE_REMOTE) {
1.1.1.2 ! misho 350: fprintf(f, "<td>%s</td>\n<td><=</td>\n<td>%s</td>\n",
1.1 misho 351: buf2, buf);
352: } else {
1.1.1.2 ! misho 353: fprintf(f, "<td>%s</td>\n<td>=></td>\n<td>%s</td>\n",
1.1 misho 354: buf, buf2);
355: }
356: } else {
1.1.1.2 ! misho 357: fprintf(f, "<td> </td>\n");
! 358: fprintf(f, "<td> </td>\n");
! 359: fprintf(f, "<td colspan=\"3\"> </td>\n");
1.1 misho 360: }
361: if (priv) {
362: switch (L->state) {
363: case PHYS_STATE_DOWN:
1.1.1.2 ! misho 364: fprintf(f, "<td><a href=\"/cmd?link%%20%s&open\">[Open]</a></td>\n",
1.1 misho 365: L->name);
366: break;
367: case PHYS_STATE_UP:
1.1.1.2 ! misho 368: fprintf(f, "<td><a href=\"/cmd?link%%20%s&close\">[Close]</a></td>\n",
1.1 misho 369: L->name);
370: break;
371: default:
1.1.1.2 ! misho 372: fprintf(f, "<td><a href=\"/cmd?link%%20%s&open\">[Open]</a> <a href=\"/cmd?link%%20%s&close\">[Close]</a></td>\n",
1.1 misho 373: L->name, L->name);
374: }
375: }
1.1.1.2 ! misho 376: fprintf(f, "</tr>\n");
1.1 misho 377: }
378: }
379: }
380: }
381: for (b = 0; b<gNumReps; b++) {
382: if ((R=gReps[b]) != NULL) {
383: int shown = 0;
384: #define FSM_COLOR(s) (((s)==ST_OPENED)?"g":(((s)==ST_INITIAL)?"r":"y"))
385: #define PHYS_COLOR(s) (((s)==PHYS_STATE_UP)?"g":(((s)==PHYS_STATE_DOWN)?"r":"y"))
386: int rows = (R->links[0]?1:0) + (R->links[1]?1:0);
387: if (rows == 0)
388: rows = 1;
1.1.1.2 ! misho 389: fprintf(f, "<tr>\n");
! 390: fprintf(f, "<td rowspan=\"%d\" colspan=\"6\">Repeater</td>\n", rows);
! 391: fprintf(f, "<td rowspan=\"%d\" class=\"%s\"><a href=\"/cmd?rep%%20%s&show%%20repeater\">%s</a></td>\n",
1.1 misho 392: rows, R->p_up?"g":"r", R->name, R->name);
393: for (l = 0; l < 2; l++) {
394: if ((L=R->links[l]) != NULL) {
395: if (shown)
1.1.1.2 ! misho 396: fprintf(f, "<tr>\n");
! 397: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20device\">%s</a></td>\n",
1.1 misho 398: PHYS_COLOR(L->state), L->name, L->name);
1.1.1.2 ! misho 399: fprintf(f, "<td colspan=\"2\"> </td>\n");
! 400: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20device\">%s</a></td>\n",
1.1 misho 401: PHYS_COLOR(L->state), L->name, L->type?L->type->name:"");
1.1.1.2 ! misho 402: fprintf(f, "<td class=\"%s\"><a href=\"/cmd?link%%20%s&show%%20device\">%s</a></td>\n",
1.1 misho 403: PHYS_COLOR(L->state), L->name, gPhysStateNames[L->state]);
404: if (L->state != PHYS_STATE_DOWN) {
405: PhysGetPeerAddr(L, buf, sizeof(buf));
1.1.1.2 ! misho 406: fprintf(f, "<td>%s</td>\n", buf);
1.1 misho 407: if (L->bund != NULL)
1.1.1.2 ! misho 408: fprintf(f, "<td>%s</td>\n", inet_ntoa(L->bund->ipcp.peer_addr));
1.1 misho 409: else
1.1.1.2 ! misho 410: fprintf(f, "<td> </td>\n");
1.1 misho 411: PhysGetCallingNum(L, buf, sizeof(buf));
412: PhysGetCalledNum(L, buf2, sizeof(buf2));
413: if (PhysGetOriginate(L) == LINK_ORIGINATE_REMOTE) {
1.1.1.2 ! misho 414: fprintf(f, "<td>%s</td>\n<td><=</td>\n<td>%s</td>\n",
1.1 misho 415: buf2, buf);
416: } else {
1.1.1.2 ! misho 417: fprintf(f, "<td>%s</td>\n<td>=></td>\n<td>%s</td>\n",
1.1 misho 418: buf, buf2);
419: }
420: } else {
1.1.1.2 ! misho 421: fprintf(f, "<td> </td>\n");
! 422: fprintf(f, "<td> </td>\n");
! 423: fprintf(f, "<td colspan=\"3\"> </td>\n");
1.1 misho 424: }
1.1.1.2 ! misho 425: fprintf(f, "<td> </td>\n");
! 426: fprintf(f, "</tr>\n");
1.1 misho 427:
428: shown = 1;
429: }
430: }
431: if (!shown) {
1.1.1.2 ! misho 432: fprintf(f, "<td colspan=\"11\"> </td>\n");
! 433: fprintf(f, "</tr>\n");
1.1 misho 434: }
435: }
436: }
1.1.1.2 ! misho 437: fprintf(f, "</tbody>\n</table>\n");
! 438: }
! 439:
! 440: static void
! 441: WebShowJSONSummary(FILE *f, int priv)
! 442: {
! 443: int b,l;
! 444: Bund B;
! 445: Link L;
! 446: Rep R;
! 447: char buf[64],buf2[64];
! 448:
! 449: int first_l = 1;
! 450: fprintf(f, "{\"links\":[\n");
! 451: for (b = 0; b<gNumLinks; b++) {
! 452: if ((L=gLinks[b]) != NULL && L->bund == NULL && L->rep == NULL) {
! 453: if (first_l) {
! 454: fprintf(f, "{\n");
! 455: first_l = 0;
! 456: } else
! 457: fprintf(f, ",\n{\n");
! 458:
! 459: fprintf(f, "\"link\": \"%s\",\n", L->name);
! 460: fprintf(f, "\"lcp\": \"%s\",\n", FsmStateName(L->lcp.fsm.state));
! 461: fprintf(f, "\"auth\": \"%s\",\n", L->lcp.auth.params.authname);
! 462: fprintf(f, "\"type\": \"%s\",\n", L->type?L->type->name:"");
! 463: fprintf(f, "\"state\": \"%s\",\n", gPhysStateNames[L->state]);
! 464:
! 465: if (L->state != PHYS_STATE_DOWN) {
! 466: PhysGetPeerAddr(L, buf, sizeof(buf));
! 467: fprintf(f, "\"peer_ip\": \"%s\",\n", buf);
! 468:
! 469: PhysGetCallingNum(L, buf, sizeof(buf));
! 470: PhysGetCalledNum(L, buf2, sizeof(buf2));
! 471: if (PhysGetOriginate(L) == LINK_ORIGINATE_REMOTE) {
! 472: fprintf(f, "\"calling_num\": \"%s\",\n", buf);
! 473: fprintf(f, "\"called_num\": \"%s\"\n", buf2);
! 474: } else {
! 475: fprintf(f, "\"calling_num\": \"%s\",\n", buf2);
! 476: fprintf(f, "\"called_num\": \"%s\"\n", buf);
! 477: }
! 478: } else {
! 479: fprintf(f, "\"calling_num\": \"%s\",\n", "");
! 480: fprintf(f, "\"called_num\": \"%s\"\n", "");
! 481: }
! 482: fprintf(f, "}\n");
! 483: }
! 484: }
! 485: fprintf(f, "],\n");
! 486:
! 487: int first_b = 1;
! 488: fprintf(f, "\"bundles\":[\n");
! 489: for (b = 0; b<gNumBundles; b++) {
! 490: if ((B=gBundles[b]) != NULL) {
! 491: if (first_b) {
! 492: fprintf(f, "{\n");
! 493: first_b = 0;
! 494: } else
! 495: fprintf(f, ",\n{\n");
! 496:
! 497: fprintf(f, "\"bundle\": \"%s\",\n", B->name);
! 498: fprintf(f, "\"iface\": \"%s\",\n", B->iface.ifname);
! 499: fprintf(f, "\"state\": \"%s\",\n", (B->iface.up?"Up":"Down"));
! 500: fprintf(f, "\"ipcp\": \"%s\",\n", FsmStateName(B->ipcp.fsm.state));
! 501: fprintf(f, "\"ipv6cp\": \"%s\",\n", FsmStateName(B->ipv6cp.fsm.state));
! 502: fprintf(f, "\"ccp\": \"%s\",\n", FsmStateName(B->ccp.fsm.state));
! 503: fprintf(f, "\"ecp\": \"%s\",\n", FsmStateName(B->ecp.fsm.state));
! 504:
! 505: int first_l = 1;
! 506: fprintf(f, "\"links\":[\n");
! 507: for (l = 0; l < NG_PPP_MAX_LINKS; l++) {
! 508: if ((L=B->links[l]) != NULL) {
! 509: if (first_l) {
! 510: fprintf(f, "{\n");
! 511: first_l = 0;
! 512: } else
! 513: fprintf(f, ",\n{\n");
! 514:
! 515: fprintf(f, "\"link\": \"%s\",\n", L->name);
! 516: fprintf(f, "\"lcp\": \"%s\",\n", FsmStateName(L->lcp.fsm.state));
! 517: fprintf(f, "\"auth\": \"%s\",\n", L->lcp.auth.params.authname);
! 518: fprintf(f, "\"type\": \"%s\",\n", L->type?L->type->name:"");
! 519: fprintf(f, "\"state\": \"%s\",\n", gPhysStateNames[L->state]);
! 520:
! 521: if (L->state != PHYS_STATE_DOWN) {
! 522: PhysGetPeerAddr(L, buf, sizeof(buf));
! 523: fprintf(f, "\"peer_ip\": \"%s\",\n", buf);
! 524:
! 525: if (L->bund != NULL)
! 526: fprintf(f, "\"ipcp_ip\": \"%s\",\n", inet_ntoa(L->bund->ipcp.peer_addr));
! 527: else
! 528: fprintf(f, "\"ipcp_ip\": \"%s\",\n", "");
! 529:
! 530: PhysGetCallingNum(L, buf, sizeof(buf));
! 531: PhysGetCalledNum(L, buf2, sizeof(buf2));
! 532: if (PhysGetOriginate(L) == LINK_ORIGINATE_REMOTE) {
! 533: fprintf(f, "\"calling_num\": \"%s\",\n", buf);
! 534: fprintf(f, "\"called_num\": \"%s\"\n", buf2);
! 535: } else {
! 536: fprintf(f, "\"calling_num\": \"%s\",\n", buf2);
! 537: fprintf(f, "\"called_num\": \"%s\"\n", buf);
! 538: }
! 539: } else {
! 540: fprintf(f, "\"calling_num\": \"%s\",\n", "");
! 541: fprintf(f, "\"called_num\": \"%s\"\n", "");
! 542: }
! 543: fprintf(f, "}\n");
! 544: }
! 545: }
! 546: fprintf(f, "]\n}\n");
! 547: }
! 548: }
! 549: fprintf(f, "],\n");
! 550:
! 551: int first_r = 1;
! 552: fprintf(f, "\"repeaters\":[\n");
! 553: for (b = 0; b<gNumReps; b++) {
! 554: if ((R=gReps[b]) != NULL) {
! 555: if (first_r) {
! 556: fprintf(f, "{\n");
! 557: first_r = 0;
! 558: } else
! 559: fprintf(f, ",\n{\n");
! 560:
! 561: fprintf(f, "\"repeater\": \"%s\",\n", R->name);
! 562:
! 563: int first_l = 1;
! 564: fprintf(f, "\"links\":[\n");
! 565: for (l = 0; l < 2; l++) {
! 566: if ((L=R->links[l]) != NULL) {
! 567: if (first_l) {
! 568: fprintf(f, "{\n");
! 569: first_l = 0;
! 570: } else
! 571: fprintf(f, ",\n{\n");
! 572:
! 573: fprintf(f, "\"link\": \"%s\",\n", L->name);
! 574: fprintf(f, "\"type\": \"%s\",\n", L->type?L->type->name:"");
! 575: fprintf(f, "\"state\": \"%s\",\n", gPhysStateNames[L->state]);
! 576:
! 577: if (L->state != PHYS_STATE_DOWN) {
! 578: PhysGetPeerAddr(L, buf, sizeof(buf));
! 579: fprintf(f, "\"peer_ip\": \"%s\",\n", buf);
! 580:
! 581: if (L->bund != NULL)
! 582: fprintf(f, "\"ipcp_ip\": \"%s\",\n", inet_ntoa(L->bund->ipcp.peer_addr));
! 583: else
! 584: fprintf(f, "\"ipcp_ip\": \"%s\",\n", "");
! 585:
! 586: PhysGetCallingNum(L, buf, sizeof(buf));
! 587: PhysGetCalledNum(L, buf2, sizeof(buf2));
! 588: if (PhysGetOriginate(L) == LINK_ORIGINATE_REMOTE) {
! 589: fprintf(f, "\"calling_num\": \"%s\",\n", buf);
! 590: fprintf(f, "\"called_num\": \"%s\"\n", buf2);
! 591: } else {
! 592: fprintf(f, "\"calling_num\": \"%s\",\n", buf2);
! 593: fprintf(f, "\"called_num\": \"%s\"\n", buf);
! 594: }
! 595: } else {
! 596: fprintf(f, "\"calling_num\": \"%s\",\n", "");
! 597: fprintf(f, "\"called_num\": \"%s\"\n", "");
! 598: }
! 599: fprintf(f, "}\n");
! 600: }
! 601: }
! 602: fprintf(f, "]\n");
! 603:
! 604: if (b == (gNumReps - 1)) {
! 605: fprintf(f, "}\n");
! 606: } else {
! 607: fprintf(f, "},\n");
! 608: }
! 609: }
! 610: }
! 611: fprintf(f, "]}\n");
1.1 misho 612: }
613:
614: static void
615: WebRunBinCmd(FILE *f, const char *query, int priv)
616: {
617: Console c = &gConsole;
618: struct console_session css;
619: ConsoleSession cs = &css;
620: char *buf;
621: char *tmp;
622: int argc, k;
623: char *argv[MAX_CONSOLE_ARGS];
624:
625: memset(cs, 0, sizeof(*cs));
626:
627: cs->cookie = f;
628: cs->console = c;
629: cs->close = NULL;
630: cs->write = WebConsoleSessionWrite;
631: cs->writev = WebConsoleSessionWriteV;
632: cs->prompt = WebConsoleSessionShowPrompt;
633: cs->context.cs = cs;
634: cs->context.priv = priv;
635:
636: tmp = buf = Mstrdup(MB_WEB, query);
637: for (argc = 0; (argv[argc] = strsep(&tmp, "&")) != NULL;)
638: if (argv[argc][0] != '\0')
639: if (++argc >= MAX_CONSOLE_ARGS)
640: break;
641:
642: for (k = 0; k < argc; k++) {
643: int ac, rtn;
644: char *av[MAX_CONSOLE_ARGS];
645: char *buf1;
646:
647: buf1 = Malloc(MB_WEB, strlen(argv[k]) + 1);
648: http_request_url_decode(argv[k], buf1);
649: Log2(LG_CONSOLE, ("[%s] WEB: %s",
650: cs->context.lnk ? cs->context.lnk->name :
651: (cs->context.bund? cs->context.bund->name : ""),
652: buf1));
653: ac = ParseLine(buf1, av, sizeof(av) / sizeof(*av), 0);
654: cs->context.errmsg[0] = 0;
655: rtn = DoCommandTab(&cs->context, gCommands, ac, av);
656: Freee(buf1);
657: fprintf(f, "RESULT: %d %s\n", rtn, cs->context.errmsg);
658: }
659: Freee(buf);
660: RESETREF(cs->context.lnk, NULL);
661: RESETREF(cs->context.bund, NULL);
662: RESETREF(cs->context.rep, NULL);
663: }
664:
665: static void
666: WebRunCmd(FILE *f, const char *query, int priv)
667: {
668: Console c = &gConsole;
669: struct console_session css;
670: ConsoleSession cs = &css;
671: char *buf;
672: char *tmp;
673: int argc, k;
674: char *argv[MAX_CONSOLE_ARGS];
675:
676: memset(cs, 0, sizeof(*cs));
677:
678: cs->cookie = f;
679: cs->console = c;
680: cs->close = NULL;
681: cs->write = WebConsoleSessionWrite;
682: cs->writev = WebConsoleSessionWriteV;
683: cs->prompt = WebConsoleSessionShowPrompt;
684: cs->context.cs = cs;
685: cs->context.priv = priv;
686:
687: tmp = buf = Mstrdup(MB_WEB, query);
688: for (argc = 0; (argv[argc] = strsep(&tmp, "&")) != NULL;)
689: if (argv[argc][0] != '\0')
690: if (++argc >= MAX_CONSOLE_ARGS)
691: break;
692:
1.1.1.2 ! misho 693: fprintf(f, "<p>\n<a href=\"/\">Back</a>\n</p>\n");
1.1 misho 694:
695: if (argc == 0) {
1.1.1.2 ! misho 696: fprintf(f, "<p>No command cpecified!</p>\n");
1.1 misho 697: goto done;
698: }
699:
1.1.1.2 ! misho 700: fprintf(f, "<pre>\n");
1.1 misho 701: for (k = 0; k < argc; k++) {
702: int ac;
703: char *av[MAX_CONSOLE_ARGS];
704: char *buf1;
705:
706: buf1 = Malloc(MB_WEB, strlen(argv[k]) + 1);
707: http_request_url_decode(argv[k], buf1);
708: Log2(LG_CONSOLE, ("[%s] WEB: %s",
709: cs->context.lnk ? cs->context.lnk->name :
710: (cs->context.bund? cs->context.bund->name : ""),
711: buf1));
712:
713: cs->prompt(cs);
714: cs->write(cs, "%s\n", buf1);
715:
716: ac = ParseLine(buf1, av, sizeof(av) / sizeof(*av), 0);
717: DoCommand(&cs->context, ac, av, NULL, 0);
718: Freee(buf1);
719: }
1.1.1.2 ! misho 720: fprintf(f, "</pre>\n");
1.1 misho 721: done:
722: Freee(buf);
1.1.1.2 ! misho 723: fprintf(f, "<p>\n<a href=\"/\">Back</a>\n</p>\n");
1.1 misho 724: RESETREF(cs->context.lnk, NULL);
725: RESETREF(cs->context.bund, NULL);
726: RESETREF(cs->context.rep, NULL);
727: }
728:
729: static void
730: WebServletRunCleanup(void *cookie) {
731: GIANT_MUTEX_UNLOCK();
732: }
733:
734: static int
735: WebServletRun(struct http_servlet *servlet,
736: struct http_request *req, struct http_response *resp)
737: {
738: FILE *f;
739: const char *path;
740: const char *query;
741: int priv = 0;
742:
743: if (Enabled(&gWeb.options, WEB_AUTH)) {
744: const char *username;
745: const char *password;
746: ConsoleUser u;
747: struct console_user iu;
748:
749: /* Get username and password */
750: if ((username = http_request_get_username(req)) == NULL)
751: username = "";
752: if ((password = http_request_get_password(req)) == NULL)
753: password = "";
754:
755: strlcpy(iu.username, username, sizeof(iu.username));
756: RWLOCK_RDLOCK(gUsersLock);
757: u = ghash_get(gUsers, &iu);
758: RWLOCK_UNLOCK(gUsersLock);
759:
760: if ((u == NULL) || strcmp(u->password, password)) {
761: http_response_send_basic_auth(resp, "Access Restricted");
762: return (1);
763: }
764: priv = u->priv;
765: }
766:
767: if (!(f = http_response_get_output(resp, 1))) {
768: return 0;
769: }
770: if (!(path = http_request_get_path(req)))
771: return 0;
772: if (!(query = http_request_get_query_string(req)))
773: return 0;
774:
775: if (!strcmp(path,"/mpd.css")) {
776: http_response_set_header(resp, 0, "Content-Type", "text/css");
777: WebShowCSS(f);
1.1.1.2 ! misho 778: } else if (!strcmp(path,"/bincmd") || !strcmp(path,"/json")) {
1.1 misho 779: http_response_set_header(resp, 0, "Content-Type", "text/plain");
780: http_response_set_header(resp, 1, "Pragma", "no-cache");
781: http_response_set_header(resp, 1, "Cache-Control", "no-cache, must-revalidate");
782:
783: pthread_cleanup_push(WebServletRunCleanup, NULL);
784: GIANT_MUTEX_LOCK();
1.1.1.2 ! misho 785:
! 786: if (!strcmp(path,"/bincmd"))
! 787: WebRunBinCmd(f, query, priv);
! 788: else if (!strcmp(path,"/json"))
! 789: WebShowJSONSummary(f, priv);
! 790:
1.1 misho 791: GIANT_MUTEX_UNLOCK();
792: pthread_cleanup_pop(0);
1.1.1.2 ! misho 793:
1.1 misho 794: } else if (!strcmp(path,"/") || !strcmp(path,"/cmd")) {
795: http_response_set_header(resp, 0, "Content-Type", "text/html");
796: http_response_set_header(resp, 1, "Pragma", "no-cache");
797: http_response_set_header(resp, 1, "Cache-Control", "no-cache, must-revalidate");
798:
799: pthread_cleanup_push(WebServletRunCleanup, NULL);
800: GIANT_MUTEX_LOCK();
1.1.1.2 ! misho 801:
! 802: fprintf(f, "<!DOCTYPE html>\n");
! 803: fprintf(f, "<html>\n");
! 804: fprintf(f, "<head>\n<title>Multi-link PPP Daemon for FreeBSD (mpd)</title>\n");
! 805: fprintf(f, "<link rel=\"stylesheet\" href=\"/mpd.css\" type=\"text/css\"/>\n");
! 806: fprintf(f, "</head>\n<body>\n");
! 807: fprintf(f, "<h1>Multi-link PPP Daemon for FreeBSD</h1>\n");
1.1 misho 808:
809: if (!strcmp(path,"/"))
1.1.1.2 ! misho 810: WebShowHTMLSummary(f, priv);
1.1 misho 811: else if (!strcmp(path,"/cmd"))
812: WebRunCmd(f, query, priv);
813:
814: GIANT_MUTEX_UNLOCK();
815: pthread_cleanup_pop(0);
816:
1.1.1.2 ! misho 817: fprintf(f, "</body>\n</html>\n");
1.1 misho 818: } else {
819: http_response_send_error(resp, 404, NULL);
820: }
821: return 1;
822: }
823:
824: static void
825: WebServletDestroy(struct http_servlet *servlet)
826: {
827: }
828:
829: static void
830: WebLogger(int sev, const char *fmt, ...)
831: {
832: va_list args;
833:
834: va_start(args, fmt);
835: vLogPrintf(fmt, args);
836: va_end(args);
837: }
838:
839: /*
840: * WebSetCommand()
841: */
842:
843: static int
844: WebSetCommand(Context ctx, int ac, char *av[], void *arg)
845: {
846: Web w = &gWeb;
847: int port;
848:
849: switch ((intptr_t)arg) {
850:
851: case SET_OPEN:
852: WebOpen(w);
853: break;
854:
855: case SET_CLOSE:
856: WebClose(w);
857: break;
858:
859: case SET_ENABLE:
860: EnableCommand(ac, av, &w->options, gConfList);
861: break;
862:
863: case SET_DISABLE:
864: DisableCommand(ac, av, &w->options, gConfList);
865: break;
866:
867: case SET_SELF:
868: if (ac < 1 || ac > 2)
869: return(-1);
870:
871: if (!ParseAddr(av[0],&w->addr, ALLOW_IPV4))
872: Error("Bogus IP address given %s", av[0]);
873:
874: if (ac == 2) {
875: port = strtol(av[1], NULL, 10);
876: if (port < 1 || port > 65535)
877: Error("Bogus port given %s", av[1]);
878: w->port=port;
879: }
880: break;
881:
882: default:
883: return(-1);
884:
885: }
886:
887: return 0;
888: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>