uIP 1.0
|
00001 /** 00002 * \addtogroup httpd 00003 * @{ 00004 */ 00005 00006 /** 00007 * \file 00008 * Скриптовый интерфейс Web-сервера 00009 * \author 00010 * Adam Dunkels <adam@sics.se> 00011 * 00012 */ 00013 00014 /* 00015 * Copyright (c) 2001-2006, Adam Dunkels. 00016 * Все права зарезервированы. * 00017 * Повторное распространение, использование в исходном и двоичном виде, 00018 * с модификацией или без - разрешается, если выполняются следующие 00019 * условия: 00020 * 1. Распространение исходного кода должно сохранить вышеуказанную пометку 00021 * копирайта, этот список условий и следующую правовую оговорку. 00022 * 2. Распространение исходного кода должно сохранить вышеуказанную пометку 00023 * копирайта, этот список условий и следующую правовую оговорку в 00024 * документации и/или других материалах, которые будут предоставлены 00025 * вместе с распространяемыми материалами. 00026 * 3. Имя автора не может использоваться, чтобы подтвердить или продвинуть 00027 * продукты, написанные с использованием этого программного обеспечения 00028 * без специального на то разрешения. 00029 * 00030 * ЭТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ АВТОРОМ ``КАК ЕСТЬ'', БЕЗ 00031 * КАКОЙ-ЛИБО ЛЮБОЙ РАСШИРЕННОЙ ИЛИ ПОДРАЗУМЕВАЕМОЙ ГАРАНТИИ, ВКЛЮЧАЯ, 00032 * НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ГАРАНТИИ ВЫСОКОГО СПРОСА И ПРИГОДНОСТИ 00033 * ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. АВТОР НИ ПРИ КАКИХ УСЛОВИЯХ НЕ ОТВЕТСТВЕНЕН 00034 * ЗА ЛЮБЫЕ УБЫТКИ - ПРЯМЫЕ, КОСВЕННЫЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ, ОБРАЗЦОВЫЕ 00035 * ИЛИ ПОСЛЕДОВАТЕЛЬНЫЕ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ТРЕБОВАНИЯ 00036 * ЗАМЕНЫ ТОВАРА ИЛИ СЕРВИСА; ПОТЕРИ ИСПОЛЬЗОВАНИЯ, ДАННЫХ ИЛИ ВЫГОДЫ; 00037 * ИЛИ ПРЕКРАЩЕНИЕ БИЗНЕСА), ОДНАКО ВЫЗВАННЫЕ ПО ЛЮБОЙ ТЕОРИИ ОТВЕТСТВЕННОСТИ, 00038 * ЛИБО В КОНТРАКТЕ, ПРЯМОЙ ОТВЕТСТВЕННОСТИ, ЛИБО В НАРУШЕНИИ ЗАКОННЫХ ПРАВ 00039 * (ВКЛЮЧАЯ ТАК ИЛИ ИНАЧЕ НЕБРЕЖНОСТЬ), ВОЗНИКАЮЩИЕ ВСЕГДА ИЗ ИСПОЛЬЗОВАНИЯ 00040 * ЭТОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, ДАЖЕ ЕСЛИ БЫЛО ПРЕДУПРЕЖДЕНИЕ О ВОЗМОЖНОСТИ 00041 * ТАКОГО ПОВРЕЖДЕНИЯ. 00042 * 00043 * Этот файл является частью стека uIP TCP/IP. 00044 * 00045 * $Id: httpd-cgi.c,v 1.2 2006/06/11 21:46:37 adam Exp $ 00046 * 00047 */ 00048 00049 #include "uip.h" 00050 #include "psock.h" 00051 #include "httpd.h" 00052 #include "httpd-cgi.h" 00053 #include "httpd-fs.h" 00054 00055 #include <stdio.h> 00056 #include <string.h> 00057 00058 HTTPD_CGI_CALL(file, "file-stats", file_stats); 00059 HTTPD_CGI_CALL(tcp, "tcp-connections", tcp_stats); 00060 HTTPD_CGI_CALL(net, "net-stats", net_stats); 00061 00062 static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, NULL }; 00063 00064 /*---------------------------------------------------------------------------*/ 00065 static 00066 PT_THREAD(nullfunction(struct httpd_state *s, char *ptr)) 00067 { 00068 PSOCK_BEGIN(&s->sout); 00069 PSOCK_END(&s->sout); 00070 } 00071 /*---------------------------------------------------------------------------*/ 00072 httpd_cgifunction 00073 httpd_cgi(char *name) 00074 { 00075 const struct httpd_cgi_call **f; 00076 00077 /* Поиск соответствующего имени в таблице, и возврат из функции. */ 00078 for(f = calls; *f != NULL; ++f) { 00079 if(strncmp((*f)->name, name, strlen((*f)->name)) == 0) { 00080 return (*f)->function; 00081 } 00082 } 00083 return nullfunction; 00084 } 00085 /*---------------------------------------------------------------------------*/ 00086 static unsigned short 00087 generate_file_stats(void *arg) 00088 { 00089 char *f = (char *)arg; 00090 return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, "%5u", httpd_fs_count(f)); 00091 } 00092 /*---------------------------------------------------------------------------*/ 00093 static 00094 PT_THREAD(file_stats(struct httpd_state *s, char *ptr)) 00095 { 00096 PSOCK_BEGIN(&s->sout); 00097 00098 PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, strchr(ptr, ' ') + 1); 00099 00100 PSOCK_END(&s->sout); 00101 } 00102 /*---------------------------------------------------------------------------*/ 00103 static const char closed[] = /* "CLOSED",*/ 00104 {0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0}; 00105 static const char syn_rcvd[] = /* "SYN-RCVD",*/ 00106 {0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56, 00107 0x44, 0}; 00108 static const char syn_sent[] = /* "SYN-SENT",*/ 00109 {0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e, 00110 0x54, 0}; 00111 static const char established[] = /* "ESTABLISHED",*/ 00112 {0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, 00113 0x45, 0x44, 0}; 00114 static const char fin_wait_1[] = /* "FIN-WAIT-1",*/ 00115 {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, 00116 0x54, 0x2d, 0x31, 0}; 00117 static const char fin_wait_2[] = /* "FIN-WAIT-2",*/ 00118 {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, 00119 0x54, 0x2d, 0x32, 0}; 00120 static const char closing[] = /* "CLOSING",*/ 00121 {0x43, 0x4c, 0x4f, 0x53, 0x49, 00122 0x4e, 0x47, 0}; 00123 static const char time_wait[] = /* "TIME-WAIT,"*/ 00124 {0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41, 00125 0x49, 0x54, 0}; 00126 static const char last_ack[] = /* "LAST-ACK"*/ 00127 {0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43, 00128 0x4b, 0}; 00129 00130 static const char *states[] = { 00131 closed, 00132 syn_rcvd, 00133 syn_sent, 00134 established, 00135 fin_wait_1, 00136 fin_wait_2, 00137 closing, 00138 time_wait, 00139 last_ack}; 00140 00141 00142 static unsigned short 00143 generate_tcp_stats(void *arg) 00144 { 00145 struct uip_conn *conn; 00146 struct httpd_state *s = (struct httpd_state *)arg; 00147 00148 conn = &uip_conns[s->count]; 00149 return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, 00150 "<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", 00151 htons(conn->lport), 00152 htons(conn->ripaddr[0]) >> 8, 00153 htons(conn->ripaddr[0]) & 0xff, 00154 htons(conn->ripaddr[1]) >> 8, 00155 htons(conn->ripaddr[1]) & 0xff, 00156 htons(conn->rport), 00157 states[conn->tcpstateflags & UIP_TS_MASK], 00158 conn->nrtx, 00159 conn->timer, 00160 (uip_outstanding(conn))? '*':' ', 00161 (uip_stopped(conn))? '!':' '); 00162 } 00163 /*---------------------------------------------------------------------------*/ 00164 static 00165 PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr)) 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 /* UIP_STATISTICS */ 00199 00200 PSOCK_END(&s->sout); 00201 } 00202 /*---------------------------------------------------------------------------*/ 00203 /** @} */