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
00047
00048 #include "uip.h"
00049 #include "psock.h"
00050 #include "httpd.h"
00051 #include "httpd-cgi.h"
00052 #include "httpd-fs.h"
00053
00054 #include <stdio.h>
00055 #include <string.h>
00056
00057 HTTPD_CGI_CALL(file, "file-stats", file_stats);
00058 HTTPD_CGI_CALL(tcp, "tcp-connections", tcp_stats);
00059 HTTPD_CGI_CALL(net, "net-stats", net_stats);
00060
00061 static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, NULL };
00062
00063
00064 static
00065 PT_THREAD(nullfunction(struct httpd_state *s, char *ptr))
00066 {
00067 PSOCK_BEGIN(&s->sout);
00068 PSOCK_END(&s->sout);
00069 }
00070
00071 httpd_cgifunction
00072 httpd_cgi(char *name)
00073 {
00074 const struct httpd_cgi_call **f;
00075
00076
00077 for(f = calls; *f != NULL; ++f) {
00078 if(strncmp((*f)->name, name, strlen((*f)->name)) == 0) {
00079 return (*f)->function;
00080 }
00081 }
00082 return nullfunction;
00083 }
00084
00085 static unsigned short
00086 generate_file_stats(void *arg)
00087 {
00088 char *f = (char *)arg;
00089 return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, "%5u", httpd_fs_count(f));
00090 }
00091
00092 static
00093 PT_THREAD(file_stats(struct httpd_state *s, char *ptr))
00094 {
00095 PSOCK_BEGIN(&s->sout);
00096
00097 PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, strchr(ptr, ' ') + 1);
00098
00099 PSOCK_END(&s->sout);
00100 }
00101
00102 static const char closed[] =
00103 {0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0};
00104 static const char syn_rcvd[] =
00105 {0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56,
00106 0x44, 0};
00107 static const char syn_sent[] =
00108 {0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e,
00109 0x54, 0};
00110 static const char established[] =
00111 {0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48,
00112 0x45, 0x44, 0};
00113 static const char fin_wait_1[] =
00114 {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
00115 0x54, 0x2d, 0x31, 0};
00116 static const char fin_wait_2[] =
00117 {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
00118 0x54, 0x2d, 0x32, 0};
00119 static const char closing[] =
00120 {0x43, 0x4c, 0x4f, 0x53, 0x49,
00121 0x4e, 0x47, 0};
00122 static const char time_wait[] =
00123 {0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41,
00124 0x49, 0x54, 0};
00125 static const char last_ack[] =
00126 {0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43,
00127 0x4b, 0};
00128
00129 static const char *states[] = {
00130 closed,
00131 syn_rcvd,
00132 syn_sent,
00133 established,
00134 fin_wait_1,
00135 fin_wait_2,
00136 closing,
00137 time_wait,
00138 last_ack};
00139
00140
00141 static unsigned short
00142 generate_tcp_stats(void *arg)
00143 {
00144 struct uip_conn *conn;
00145 struct httpd_state *s = (struct httpd_state *)arg;
00146
00147 conn = &uip_conns[s->count];
00148 return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,
00149 "<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",
00150 htons(conn->lport),
00151 htons(conn->ripaddr[0]) >> 8,
00152 htons(conn->ripaddr[0]) & 0xff,
00153 htons(conn->ripaddr[1]) >> 8,
00154 htons(conn->ripaddr[1]) & 0xff,
00155 htons(conn->rport),
00156 states[conn->tcpstateflags & UIP_TS_MASK],
00157 conn->nrtx,
00158 conn->timer,
00159 (uip_outstanding(conn))? '*':' ',
00160 (uip_stopped(conn))? '!':' ');
00161 }
00162
00163 static
00164 PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr))
00165 {
00166
00167 PSOCK_BEGIN(&s->sout);
00168
00169 for(s->count = 0; s->count < UIP_CONNS; ++s->count) {
00170 if((uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) {
00171 PSOCK_GENERATOR_SEND(&s->sout, generate_tcp_stats, s);
00172 }
00173 }
00174
00175 PSOCK_END(&s->sout);
00176 }
00177
00178 static unsigned short
00179 generate_net_stats(void *arg)
00180 {
00181 struct httpd_state *s = (struct httpd_state *)arg;
00182 return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE,
00183 "%5u\n", ((uip_stats_t *)&uip_stat)[s->count]);
00184 }
00185
00186 static
00187 PT_THREAD(net_stats(struct httpd_state *s, char *ptr))
00188 {
00189 PSOCK_BEGIN(&s->sout);
00190
00191 #if UIP_STATISTICS
00192
00193 for(s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t);
00194 ++s->count) {
00195 PSOCK_GENERATOR_SEND(&s->sout, generate_net_stats, s);
00196 }
00197
00198 #endif
00199
00200 PSOCK_END(&s->sout);
00201 }
00202
00203