uIP 1.0
C:/asm/STM32-ethernet/ENC28J60prj/uip-master/apps/webserver/httpd-cgi.c
См. документацию.
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 /** @} */