Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2001, Adam Dunkels. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. The name of the author may not be used to endorse or promote 00014 * products derived from this software without specific prior 00015 * written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 00018 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00019 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00021 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00023 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00025 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00026 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00027 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 * 00029 * This file is part of the uIP TCP/IP stack. 00030 * 00031 * $Id: httpd-cgi.c,v 1.2 2010/10/19 18:29:05 adamdunkels Exp $ 00032 * 00033 */ 00034 00035 /* 00036 * This file includes functions that are called by the web server 00037 * scripts. The functions takes no argument, and the return value is 00038 * interpreted as follows. A zero means that the function did not 00039 * complete and should be invoked for the next packet as well. A 00040 * non-zero value indicates that the function has completed and that 00041 * the web server should move along to the next script line. 00042 * 00043 */ 00044 00045 00046 #include "contiki-net.h" 00047 #include "httpd.h" 00048 #include "httpd-cgi.h" 00049 #include "httpd-fs.h" 00050 00051 #include "lib/petsciiconv.h" 00052 00053 #include <stdio.h> 00054 #include <string.h> 00055 00056 00057 static struct httpd_cgi_call *calls = NULL; 00058 00059 /*struct cgifunction { 00060 char *name; 00061 httpd_cgifunction function; 00062 }; 00063 00064 static struct cgifunction cgitab[] = { 00065 {"file-stats", file_stats}, 00066 {"tcp-connections", tcp_stats}, 00067 {"processes", processes}, 00068 {NULL, NULL} 00069 };*/ 00070 00071 00072 static const char closed[] = /* "CLOSED",*/ 00073 {0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0}; 00074 static const char syn_rcvd[] = /* "SYN-RCVD",*/ 00075 {0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56, 00076 0x44, 0}; 00077 static const char syn_sent[] = /* "SYN-SENT",*/ 00078 {0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e, 00079 0x54, 0}; 00080 static const char established[] = /* "ESTABLISHED",*/ 00081 {0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, 00082 0x45, 0x44, 0}; 00083 static const char fin_wait_1[] = /* "FIN-WAIT-1",*/ 00084 {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, 00085 0x54, 0x2d, 0x31, 0}; 00086 static const char fin_wait_2[] = /* "FIN-WAIT-2",*/ 00087 {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, 00088 0x54, 0x2d, 0x32, 0}; 00089 static const char closing[] = /* "CLOSING",*/ 00090 {0x43, 0x4c, 0x4f, 0x53, 0x49, 00091 0x4e, 0x47, 0}; 00092 static const char time_wait[] = /* "TIME-WAIT,"*/ 00093 {0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41, 00094 0x49, 0x54, 0}; 00095 static const char last_ack[] = /* "LAST-ACK"*/ 00096 {0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43, 00097 0x4b, 0}; 00098 static const char none[] = "NONE"; 00099 static const char init[] = "INIT"; 00100 static const char running[] = "RUNNING"; 00101 static const char needs_poll[] = "NEEDS POLL"; 00102 00103 static const char *states[] = { 00104 closed, 00105 syn_rcvd, 00106 syn_sent, 00107 established, 00108 fin_wait_1, 00109 fin_wait_2, 00110 closing, 00111 time_wait, 00112 last_ack, 00113 none, 00114 init, 00115 running, 00116 needs_poll}; 00117 00118 00119 /*---------------------------------------------------------------------------*/ 00120 static 00121 PT_THREAD(nullfunction(struct httpd_state *s, char *ptr)) 00122 { 00123 PSOCK_BEGIN(&s->sout); 00124 PSOCK_END(&s->sout); 00125 } 00126 /*---------------------------------------------------------------------------*/ 00127 httpd_cgifunction 00128 httpd_cgi(char *name) 00129 { 00130 struct httpd_cgi_call *f; 00131 00132 /* Find the matching name in the table, return the function. */ 00133 for(f = calls; f != NULL; f = f->next) { 00134 if(strncmp(f->name, name, strlen(f->name)) == 0) { 00135 return f->function; 00136 } 00137 } 00138 return nullfunction; 00139 } 00140 /*---------------------------------------------------------------------------*/ 00141 static unsigned short 00142 generate_file_stats(void *arg) 00143 { 00144 char *f = (char *)arg; 00145 return sprintf((char *)uip_appdata, "%5u", httpd_fs_count(f)); 00146 } 00147 /*---------------------------------------------------------------------------*/ 00148 static 00149 PT_THREAD(file_stats(struct httpd_state *s, char *ptr)) 00150 { 00151 PSOCK_BEGIN(&s->sout); 00152 00153 PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, (void *) (strchr(ptr, ' ') + 1)); 00154 00155 PSOCK_END(&s->sout); 00156 } 00157 /*---------------------------------------------------------------------------*/ 00158 static unsigned short 00159 make_tcp_stats(void *arg) 00160 { 00161 struct uip_conn *conn; 00162 struct httpd_state *s = (struct httpd_state *)arg; 00163 00164 conn = &uip_conns[s->u.count]; 00165 return sprintf((char *)uip_appdata, 00166 "<tr align=\"center\"><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", 00167 uip_htons(conn->lport), 00168 conn->ripaddr.u8[0], 00169 conn->ripaddr.u8[1], 00170 conn->ripaddr.u8[2], 00171 conn->ripaddr.u8[3], 00172 uip_htons(conn->rport), 00173 states[conn->tcpstateflags & UIP_TS_MASK], 00174 conn->nrtx, 00175 conn->timer, 00176 (uip_outstanding(conn))? '*':' ', 00177 (uip_stopped(conn))? '!':' '); 00178 } 00179 /*---------------------------------------------------------------------------*/ 00180 static 00181 PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr)) 00182 { 00183 00184 PSOCK_BEGIN(&s->sout); 00185 00186 for(s->u.count = 0; s->u.count < UIP_CONNS; ++s->u.count) { 00187 if((uip_conns[s->u.count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) { 00188 PSOCK_GENERATOR_SEND(&s->sout, make_tcp_stats, s); 00189 } 00190 } 00191 00192 PSOCK_END(&s->sout); 00193 } 00194 /*---------------------------------------------------------------------------*/ 00195 static unsigned short 00196 make_processes(void *p) 00197 { 00198 char name[40]; 00199 00200 strncpy(name, PROCESS_NAME_STRING((struct process *)p), 40); 00201 petsciiconv_toascii(name, 40); 00202 00203 return sprintf((char *)uip_appdata, 00204 "<tr align=\"center\"><td>%p</td><td>%s</td><td>%p</td><td>%s</td></tr>\r\n", 00205 p, name, 00206 (char *)((struct process *)p)->thread, 00207 states[9 + ((struct process *)p)->state]); 00208 } 00209 /*---------------------------------------------------------------------------*/ 00210 static 00211 PT_THREAD(processes(struct httpd_state *s, char *ptr)) 00212 { 00213 PSOCK_BEGIN(&s->sout); 00214 for(s->u.ptr = PROCESS_LIST(); s->u.ptr != NULL; s->u.ptr = ((struct process *)s->u.ptr)->next) { 00215 PSOCK_GENERATOR_SEND(&s->sout, make_processes, s->u.ptr); 00216 } 00217 PSOCK_END(&s->sout); 00218 } 00219 /*---------------------------------------------------------------------------*/ 00220 void 00221 httpd_cgi_add(struct httpd_cgi_call *c) 00222 { 00223 struct httpd_cgi_call *l; 00224 00225 c->next = NULL; 00226 if(calls == NULL) { 00227 calls = c; 00228 } else { 00229 for(l = calls; l->next != NULL; l = l->next); 00230 l->next = c; 00231 } 00232 } 00233 /*---------------------------------------------------------------------------*/ 00234 00235 HTTPD_CGI_CALL(file, "file-stats", file_stats); 00236 HTTPD_CGI_CALL(tcp, "tcp-connections", tcp_stats); 00237 HTTPD_CGI_CALL(proc, "processes", processes); 00238 00239 void 00240 httpd_cgi_init(void) 00241 { 00242 httpd_cgi_add(&file); 00243 httpd_cgi_add(&tcp); 00244 httpd_cgi_add(&proc); 00245 } 00246 /*---------------------------------------------------------------------------*/