2 * Copyright (c) 2001, Adam Dunkels.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote
14 * products derived from this software without specific prior
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * This file is part of the uIP TCP/IP stack.
31 * $Id: httpd-cgi.c,v 1.14 2008/10/14 11:07:57 adamdunkels Exp $
36 * This file includes functions that are called by the web server
37 * scripts. The functions takes no argument, and the return value is
38 * interpreted as follows. A zero means that the function did not
39 * complete and should be invoked for the next packet as well. A
40 * non-zero value indicates that the function has completed and that
41 * the web server should move along to the next script line.
48 #include "contiki-net.h"
50 #include "httpd-cgi.h"
53 #include "lib/petsciiconv.h"
55 static struct httpd_cgi_call
*calls
= NULL
;
57 static const char closed
[] = /* "CLOSED",*/
58 {0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0};
59 static const char syn_rcvd
[] = /* "SYN-RCVD",*/
60 {0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56,
62 static const char syn_sent
[] = /* "SYN-SENT",*/
63 {0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e,
65 static const char established
[] = /* "ESTABLISHED",*/
66 {0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49,
67 0x53, 0x48, 0x45, 0x44, 0};
68 static const char fin_wait_1
[] = /* "FIN-WAIT-1",*/
69 {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
71 static const char fin_wait_2
[] = /* "FIN-WAIT-2",*/
72 {0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49,
74 static const char closing
[] = /* "CLOSING",*/
75 {0x43, 0x4c, 0x4f, 0x53, 0x49,
77 static const char time_wait
[] = /* "TIME-WAIT,"*/
78 {0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41,
80 static const char last_ack
[] = /* "LAST-ACK"*/
81 {0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43,
83 static const char none
[] = /* "NONE"*/
84 {0x4e, 0x4f, 0x4e, 0x45, 0};
85 static const char running
[] = /* "RUNNING"*/
86 {0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47,
88 static const char called
[] = /* "CALLED"*/
89 {0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0};
90 static const char file_name
[] = /* "file-stats"*/
91 {0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74,
93 static const char tcp_name
[] = /* "tcp-connections"*/
94 {0x74, 0x63, 0x70, 0x2d, 0x63, 0x6f, 0x6e,
95 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
97 static const char proc_name
[] = /* "processes"*/
98 {0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
101 static const char *states
[] = {
115 /*---------------------------------------------------------------------------*/
117 PT_THREAD(nullfunction(struct httpd_state
*s
, char *ptr
))
119 PSOCK_BEGIN(&s
->sout
);
122 /*---------------------------------------------------------------------------*/
124 httpd_cgi(char *name
)
126 struct httpd_cgi_call
*f
;
128 /* Find the matching name in the table, return the function. */
129 for(f
= calls
; f
!= NULL
; f
= f
->next
) {
130 if(strncmp(f
->name
, name
, strlen(f
->name
)) == 0) {
136 /*---------------------------------------------------------------------------*/
137 static unsigned short
138 generate_file_stats(void *arg
)
140 char *f
= (char *)arg
;
141 return snprintf((char *)uip_appdata
, uip_mss(), "%5u", httpd_fs_count(f
));
143 /*---------------------------------------------------------------------------*/
145 PT_THREAD(file_stats(struct httpd_state
*s
, char *ptr
))
147 PSOCK_BEGIN(&s
->sout
);
149 PSOCK_GENERATOR_SEND(&s
->sout
, generate_file_stats
, (void *) (strchr(ptr
, ' ') + 1));
153 /*---------------------------------------------------------------------------*/
154 static unsigned short
155 make_tcp_stats(void *arg
)
157 struct uip_conn
*conn
;
158 struct httpd_state
*s
= (struct httpd_state
*)arg
;
160 conn
= &uip_conns
[s
->u
.count
];
161 return snprintf((char *)uip_appdata
, uip_mss(),
162 "<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",
169 states
[conn
->tcpstateflags
& UIP_TS_MASK
],
172 (uip_outstanding(conn
))? '*':' ',
173 (uip_stopped(conn
))? '!':' ');
175 /*---------------------------------------------------------------------------*/
177 PT_THREAD(tcp_stats(struct httpd_state
*s
, char *ptr
))
180 PSOCK_BEGIN(&s
->sout
);
182 for(s
->u
.count
= 0; s
->u
.count
< UIP_CONNS
; ++s
->u
.count
) {
183 if((uip_conns
[s
->u
.count
].tcpstateflags
& UIP_TS_MASK
) != UIP_CLOSED
) {
184 PSOCK_GENERATOR_SEND(&s
->sout
, make_tcp_stats
, s
);
190 /*---------------------------------------------------------------------------*/
191 static unsigned short
192 make_processes(void *p
)
196 strncpy(name
, ((struct process
*)p
)->name
, 40);
197 petsciiconv_toascii(name
, 40);
199 return snprintf((char *)uip_appdata
, uip_mss(),
200 "<tr align=\"center\"><td>%p</td><td>%s</td><td>%p</td><td>%s</td></tr>\r\n",
202 *((char **)&(((struct process
*)p
)->thread
)),
203 states
[9 + ((struct process
*)p
)->state
]);
205 /*---------------------------------------------------------------------------*/
207 PT_THREAD(processes(struct httpd_state
*s
, char *ptr
))
209 PSOCK_BEGIN(&s
->sout
);
210 for(s
->u
.ptr
= PROCESS_LIST(); s
->u
.ptr
!= NULL
; s
->u
.ptr
= ((struct process
*)s
->u
.ptr
)->next
) {
211 PSOCK_GENERATOR_SEND(&s
->sout
, make_processes
, s
->u
.ptr
);
215 /*---------------------------------------------------------------------------*/
217 httpd_cgi_add(struct httpd_cgi_call
*c
)
219 struct httpd_cgi_call
*l
;
225 for(l
= calls
; l
->next
!= NULL
; l
= l
->next
);
229 /*---------------------------------------------------------------------------*/
231 HTTPD_CGI_CALL(file
, file_name
, file_stats
);
232 HTTPD_CGI_CALL(tcp
, tcp_name
, tcp_stats
);
233 HTTPD_CGI_CALL(proc
, proc_name
, processes
);
238 httpd_cgi_add(&file
);
240 httpd_cgi_add(&proc
);
242 /*---------------------------------------------------------------------------*/