2 * Copyright (c) 2001, Swedish Institute of Computer Science.
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. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * This file is part of the lwIP TCP/IP stack.
31 * Author: Adam Dunkels <adam@sics.se>
35 #include "lwip/debug.h"
36 #include "lwip/stats.h"
38 #include <cyg/infra/testcase.h>
40 #ifdef CYGPKG_LWIP_TCP
48 /* Stack smashing arch-independent shellcode: will brick your target :-) */
49 static const char sdata[] __attribute__ ((aligned)) = {
50 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
51 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x43, 0x6f, 0x6e,
52 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a,
53 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
54 0xd, 0xa, 0xd, 0xa, 0x49, 0x74, 0x20, 0x77, 0x6f, 0x72,
55 0x6b, 0x65, 0x64, 0x2e, 0xa, };
60 /*-----------------------------------------------------------------------------------*/
62 conn_err(void *arg, err_t err)
64 struct http_state *hs;
69 /*-----------------------------------------------------------------------------------*/
71 close_conn(struct tcp_pcb *pcb, struct http_state *hs)
79 /*-----------------------------------------------------------------------------------*/
81 send_data(struct tcp_pcb *pcb, struct http_state *hs)
86 /* We cannot send more data than space available in the send
88 if(tcp_sndbuf(pcb) < hs->left) {
89 len = tcp_sndbuf(pcb);
95 err = tcp_write(pcb, hs->file, len, 0);
99 } while(err == ERR_MEM && len > 1);
106 /*-----------------------------------------------------------------------------------*/
108 http_poll(void *arg, struct tcp_pcb *pcb)
110 struct http_state *hs;
114 /* printf("Polll\n");*/
116 /* printf("Null, close\n");*/
121 if(hs->retries == 4) {
130 /*-----------------------------------------------------------------------------------*/
132 http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
134 struct http_state *hs;
148 /*-----------------------------------------------------------------------------------*/
150 http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
154 struct http_state *hs;
158 if(err == ERR_OK && p != NULL) {
160 /* Inform TCP that we have taken the data. */
161 tcp_recved(pcb, p->tot_len);
163 if(hs->file == NULL) {
167 for(i = 0; i < 40; i++) {
168 if(((char *)data + 4)[i] == ' ' ||
169 ((char *)data + 4)[i] == '\r' ||
170 ((char *)data + 4)[i] == '\n') {
171 ((char *)data + 4)[i] = 0;
176 hs->left = sizeof(sdata);
181 /* Tell TCP that we wish be to informed of data that has been
182 successfully sent by a call to the http_sent() function. */
183 tcp_sent(pcb, http_sent);
193 if(err == ERR_OK && p == NULL) {
198 /*-----------------------------------------------------------------------------------*/
200 http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
202 struct http_state *hs;
204 tcp_setprio(pcb, TCP_PRIO_MIN);
206 /* Allocate memory for the structure that holds the state of the
208 hs = mem_malloc(sizeof(struct http_state));
214 /* Initialize the structure. */
219 /* Tell TCP that this is the structure we wish to be passed for our
223 /* Tell TCP that we wish to be informed of incoming data by a call
224 to the http_recv() function. */
225 tcp_recv(pcb, http_recv);
227 tcp_err(pcb, conn_err);
229 tcp_poll(pcb, http_poll, 4);
233 /*-----------------------------------------------------------------------------------*/
235 httpd_init(void *arg)
240 tcp_bind(pcb, IP_ADDR_ANY, 80);
241 pcb = tcp_listen(pcb);
242 tcp_accept(pcb, http_accept);
244 cyg_thread_delay(1000);
248 tmain(cyg_addrword_t p)
251 sys_thread_new(httpd_init, (void*)"httpd",7);
254 #define STACK_SIZE 0x1000
255 static char stack[STACK_SIZE];
256 static cyg_thread thread_data;
257 static cyg_handle_t thread_handle;
263 // Create a main thread, so we can run the scheduler and have time 'pass'
264 cyg_thread_create(10, // Priority - just a number
266 0, // entry parameter
270 &thread_handle, // Handle
271 &thread_data // Thread data structure
273 cyg_thread_resume(thread_handle); // Start it
274 cyg_scheduler_start();
275 CYG_TEST_FAIL_FINISH("Not reached");
284 #else // def CYGPKG_LWIP_TCP
285 #define N_A_MSG "TCP support disabled"
286 #endif // def CYGFUN_KERNEL_API_C
293 CYG_TEST_NA(N_A_MSG);