adamdunkels | c7cc92a | 2003-05-28 05:21:49 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2001, Adam Dunkels. |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
| 8 | * 1. Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer. |
| 10 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. |
adamdunkels | 06f897e | 2004-06-06 05:59:20 +0000 | [diff] [blame] | 13 | * 3. The name of the author may not be used to endorse or promote |
adamdunkels | c7cc92a | 2003-05-28 05:21:49 +0000 | [diff] [blame] | 14 | * products derived from this software without specific prior |
| 15 | * written permission. |
| 16 | * |
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |
| 18 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
| 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
| 23 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 26 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | * |
| 29 | * This file is part of the uIP TCP/IP stack. |
| 30 | * |
ryohji | c615a2d | 2007-06-02 07:32:05 +0000 | [diff] [blame] | 31 | * $Id: httpd-cgi.c,v 1.10 2007/06/02 07:32:06 ryohji Exp $ |
adamdunkels | c7cc92a | 2003-05-28 05:21:49 +0000 | [diff] [blame] | 32 | * |
| 33 | */ |
| 34 | |
| 35 | /* |
| 36 | * This file includes functions that are called by the web server |
| 37 | * scripts. The functions takes no argument, and the return value is |
| 38 | * interpreted as follows. A zero means that the function did not |
| 39 | * complete and should be invoked for the next packet as well. A |
| 40 | * non-zero value indicates that the function has completed and that |
| 41 | * the web server should move along to the next script line. |
| 42 | * |
| 43 | */ |
| 44 | |
| 45 | #include "uip.h" |
| 46 | #include "httpd.h" |
| 47 | #include "httpd-cgi.h" |
| 48 | #include "httpd-fs.h" |
| 49 | |
adamdunkels | 9f20c05 | 2003-06-30 20:41:14 +0000 | [diff] [blame] | 50 | #include "petsciiconv.h" |
| 51 | |
adamdunkels | c7cc92a | 2003-05-28 05:21:49 +0000 | [diff] [blame] | 52 | #include <stdio.h> |
| 53 | #include <string.h> |
| 54 | |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 55 | static PT_THREAD(file_stats(struct httpd_state *s, char *arg)); |
| 56 | static PT_THREAD(tcp_stats(struct httpd_state *s, char *arg)); |
| 57 | static PT_THREAD(processes(struct httpd_state *s, char *arg)); |
adamdunkels | c7cc92a | 2003-05-28 05:21:49 +0000 | [diff] [blame] | 58 | |
adamdunkels | f29d888 | 2005-02-27 09:33:50 +0000 | [diff] [blame] | 59 | struct cgifunction { |
| 60 | char *name; |
| 61 | httpd_cgifunction function; |
adamdunkels | c7cc92a | 2003-05-28 05:21:49 +0000 | [diff] [blame] | 62 | }; |
| 63 | |
adamdunkels | f29d888 | 2005-02-27 09:33:50 +0000 | [diff] [blame] | 64 | static struct cgifunction cgitab[] = { |
| 65 | {"file-stats", file_stats}, |
| 66 | {"tcp-connections", tcp_stats}, |
| 67 | {"processes", processes}, |
| 68 | {NULL, NULL} |
| 69 | }; |
| 70 | |
| 71 | |
adamdunkels | c7cc92a | 2003-05-28 05:21:49 +0000 | [diff] [blame] | 72 | static const char closed[] = /* "CLOSED",*/ |
| 73 | {0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0}; |
| 74 | static const char syn_rcvd[] = /* "SYN-RCVD",*/ |
| 75 | {0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56, |
| 76 | 0x44, 0}; |
| 77 | static const char syn_sent[] = /* "SYN-SENT",*/ |
| 78 | {0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e, |
| 79 | 0x54, 0}; |
| 80 | static const char established[] = /* "ESTABLISHED",*/ |
| 81 | {0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, |
| 82 | 0x45, 0x44, 0}; |
| 83 | static const char fin_wait_1[] = /* "FIN-WAIT-1",*/ |
| 84 | {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, |
| 85 | 0x54, 0x2d, 0x31, 0}; |
| 86 | static const char fin_wait_2[] = /* "FIN-WAIT-2",*/ |
| 87 | {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, |
| 88 | 0x54, 0x2d, 0x32, 0}; |
| 89 | static const char closing[] = /* "CLOSING",*/ |
| 90 | {0x43, 0x4c, 0x4f, 0x53, 0x49, |
| 91 | 0x4e, 0x47, 0}; |
| 92 | static const char time_wait[] = /* "TIME-WAIT,"*/ |
| 93 | {0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41, |
| 94 | 0x49, 0x54, 0}; |
| 95 | static const char last_ack[] = /* "LAST-ACK"*/ |
| 96 | {0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43, |
| 97 | 0x4b, 0}; |
| 98 | |
| 99 | static const char *states[] = { |
| 100 | closed, |
| 101 | syn_rcvd, |
| 102 | syn_sent, |
| 103 | established, |
| 104 | fin_wait_1, |
| 105 | fin_wait_2, |
| 106 | closing, |
| 107 | time_wait, |
| 108 | last_ack}; |
| 109 | |
| 110 | |
adamdunkels | f29d888 | 2005-02-27 09:33:50 +0000 | [diff] [blame] | 111 | /*---------------------------------------------------------------------------*/ |
| 112 | static |
| 113 | PT_THREAD(nullfunction(struct httpd_state *s, char *ptr)) |
| 114 | { |
| 115 | PSOCK_BEGIN(&s->sout); |
| 116 | PSOCK_END(&s->sout); |
| 117 | } |
| 118 | /*---------------------------------------------------------------------------*/ |
| 119 | httpd_cgifunction |
| 120 | httpd_cgi(char *name) |
| 121 | { |
| 122 | struct cgifunction *f; |
| 123 | |
| 124 | /* Find the matching name in the table, return the function. */ |
| 125 | for(f = cgitab; f->name != NULL; ++f) { |
| 126 | if(strncmp(f->name, name, strlen(f->name)) == 0) { |
| 127 | return f->function; |
| 128 | } |
| 129 | } |
| 130 | return nullfunction; |
| 131 | } |
| 132 | /*---------------------------------------------------------------------------*/ |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 133 | static unsigned short |
adamdunkels | d251e84 | 2004-09-13 21:48:42 +0000 | [diff] [blame] | 134 | generate_file_stats(void *arg) |
adamdunkels | c7cc92a | 2003-05-28 05:21:49 +0000 | [diff] [blame] | 135 | { |
adamdunkels | d251e84 | 2004-09-13 21:48:42 +0000 | [diff] [blame] | 136 | char *f = (char *)arg; |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 137 | return sprintf((char *)uip_appdata, "%5u", httpd_fs_count(f)); |
adamdunkels | c7cc92a | 2003-05-28 05:21:49 +0000 | [diff] [blame] | 138 | } |
adamdunkels | f29d888 | 2005-02-27 09:33:50 +0000 | [diff] [blame] | 139 | /*---------------------------------------------------------------------------*/ |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 140 | static |
| 141 | PT_THREAD(file_stats(struct httpd_state *s, char *ptr)) |
| 142 | { |
oliverschmidt | a900bff | 2005-02-23 21:18:05 +0000 | [diff] [blame] | 143 | PSOCK_BEGIN(&s->sout); |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 144 | |
adamdunkels | f29d888 | 2005-02-27 09:33:50 +0000 | [diff] [blame] | 145 | PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, strchr(ptr, ' ') + 1); |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 146 | |
oliverschmidt | a900bff | 2005-02-23 21:18:05 +0000 | [diff] [blame] | 147 | PSOCK_END(&s->sout); |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 148 | } |
adamdunkels | f29d888 | 2005-02-27 09:33:50 +0000 | [diff] [blame] | 149 | /*---------------------------------------------------------------------------*/ |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 150 | static unsigned short |
adamdunkels | d251e84 | 2004-09-13 21:48:42 +0000 | [diff] [blame] | 151 | make_tcp_stats(void *arg) |
adamdunkels | c7cc92a | 2003-05-28 05:21:49 +0000 | [diff] [blame] | 152 | { |
adamdunkels | d251e84 | 2004-09-13 21:48:42 +0000 | [diff] [blame] | 153 | struct uip_conn *conn; |
| 154 | struct httpd_state *s = (struct httpd_state *)arg; |
| 155 | |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 156 | conn = &uip_conns[s->count]; |
| 157 | return sprintf((char *)uip_appdata, |
| 158 | "<tr><td>%d</td><td>%u.%u.%u.%u:%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n", |
| 159 | htons(conn->lport), |
| 160 | htons(conn->ripaddr[0]) >> 8, |
| 161 | htons(conn->ripaddr[0]) & 0xff, |
| 162 | htons(conn->ripaddr[1]) >> 8, |
| 163 | htons(conn->ripaddr[1]) & 0xff, |
| 164 | htons(conn->rport), |
| 165 | states[conn->tcpstateflags & TS_MASK], |
| 166 | conn->nrtx, |
| 167 | conn->timer, |
| 168 | (uip_outstanding(conn))? '*':' ', |
| 169 | (uip_stopped(conn))? '!':' '); |
adamdunkels | 9f20c05 | 2003-06-30 20:41:14 +0000 | [diff] [blame] | 170 | } |
adamdunkels | f29d888 | 2005-02-27 09:33:50 +0000 | [diff] [blame] | 171 | /*---------------------------------------------------------------------------*/ |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 172 | static |
| 173 | PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr)) |
adamdunkels | 9f20c05 | 2003-06-30 20:41:14 +0000 | [diff] [blame] | 174 | { |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 175 | |
oliverschmidt | a900bff | 2005-02-23 21:18:05 +0000 | [diff] [blame] | 176 | PSOCK_BEGIN(&s->sout); |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 177 | |
| 178 | for(s->count = 0; s->count < UIP_CONNS; ++s->count) { |
| 179 | if((uip_conns[s->count].tcpstateflags & TS_MASK) != CLOSED) { |
oliverschmidt | a900bff | 2005-02-23 21:18:05 +0000 | [diff] [blame] | 180 | PSOCK_GENERATOR_SEND(&s->sout, make_tcp_stats, s); |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 181 | } |
| 182 | } |
| 183 | |
oliverschmidt | a900bff | 2005-02-23 21:18:05 +0000 | [diff] [blame] | 184 | PSOCK_END(&s->sout); |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 185 | } |
adamdunkels | f29d888 | 2005-02-27 09:33:50 +0000 | [diff] [blame] | 186 | /*---------------------------------------------------------------------------*/ |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 187 | static unsigned short |
adamdunkels | d251e84 | 2004-09-13 21:48:42 +0000 | [diff] [blame] | 188 | make_processes(void *s) |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 189 | { |
adamdunkels | d251e84 | 2004-09-13 21:48:42 +0000 | [diff] [blame] | 190 | struct ek_proc *p = (struct ek_proc *)s; |
adamdunkels | 9f20c05 | 2003-06-30 20:41:14 +0000 | [diff] [blame] | 191 | char name[40]; |
| 192 | |
adamdunkels | 9f20c05 | 2003-06-30 20:41:14 +0000 | [diff] [blame] | 193 | strncpy(name, p->name, 40); |
| 194 | petsciiconv_toascii(name, 40); |
adamdunkels | 0dce2c9 | 2004-09-12 20:52:37 +0000 | [diff] [blame] | 195 | |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 196 | return sprintf((char *)uip_appdata, |
adamdunkels | d251e84 | 2004-09-13 21:48:42 +0000 | [diff] [blame] | 197 | "<tr align=\"center\"><td>%3d</td><td>%s</td><td>0x%02x</td><td>%p</td><td>%p</td><td>%p</td></tr>\r\n", |
adamdunkels | 0dce2c9 | 2004-09-12 20:52:37 +0000 | [diff] [blame] | 198 | p->id, name, p->prio, |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 199 | p->pollhandler, p->eventhandler, p->procstate); |
adamdunkels | 9f20c05 | 2003-06-30 20:41:14 +0000 | [diff] [blame] | 200 | } |
adamdunkels | f29d888 | 2005-02-27 09:33:50 +0000 | [diff] [blame] | 201 | /*---------------------------------------------------------------------------*/ |
adamdunkels | b63552d | 2004-09-12 07:15:00 +0000 | [diff] [blame] | 202 | static |
| 203 | PT_THREAD(processes(struct httpd_state *s, char *ptr)) |
adamdunkels | 1f40cee | 2003-08-05 13:52:24 +0000 | [diff] [blame] | 204 | { |
ryohji | c615a2d | 2007-06-02 07:32:05 +0000 | [diff] [blame] | 205 | static struct ek_proc *p; |
adamdunkels | 0dce2c9 | 2004-09-12 20:52:37 +0000 | [diff] [blame] | 206 | |
oliverschmidt | a900bff | 2005-02-23 21:18:05 +0000 | [diff] [blame] | 207 | PSOCK_BEGIN(&s->sout); |
adamdunkels | 1f40cee | 2003-08-05 13:52:24 +0000 | [diff] [blame] | 208 | |
adamdunkels | 0dce2c9 | 2004-09-12 20:52:37 +0000 | [diff] [blame] | 209 | for(s->count = 0; s->count < EK_CONF_MAXPROCS; ++s->count) { |
| 210 | p = ek_process(s->count); |
| 211 | if(p != NULL) { |
oliverschmidt | a900bff | 2005-02-23 21:18:05 +0000 | [diff] [blame] | 212 | PSOCK_GENERATOR_SEND(&s->sout, make_processes, p); |
adamdunkels | 0dce2c9 | 2004-09-12 20:52:37 +0000 | [diff] [blame] | 213 | } |
| 214 | } |
adamdunkels | 9f20c05 | 2003-06-30 20:41:14 +0000 | [diff] [blame] | 215 | |
oliverschmidt | a900bff | 2005-02-23 21:18:05 +0000 | [diff] [blame] | 216 | PSOCK_END(&s->sout); |
adamdunkels | 9f20c05 | 2003-06-30 20:41:14 +0000 | [diff] [blame] | 217 | } |
adamdunkels | f29d888 | 2005-02-27 09:33:50 +0000 | [diff] [blame] | 218 | /*---------------------------------------------------------------------------*/ |