00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
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
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 static const char closed[] =
00073 {0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0};
00074 static const char syn_rcvd[] =
00075 {0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56,
00076 0x44, 0};
00077 static const char syn_sent[] =
00078 {0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e,
00079 0x54, 0};
00080 static const char established[] =
00081 {0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48,
00082 0x45, 0x44, 0};
00083 static const char fin_wait_1[] =
00084 {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
00085 0x54, 0x2d, 0x31, 0};
00086 static const char fin_wait_2[] =
00087 {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
00088 0x54, 0x2d, 0x32, 0};
00089 static const char closing[] =
00090 {0x43, 0x4c, 0x4f, 0x53, 0x49,
00091 0x4e, 0x47, 0};
00092 static const char time_wait[] =
00093 {0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41,
00094 0x49, 0x54, 0};
00095 static const char 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
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, ((struct process *)p)->name, 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