]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/net/lwip_tcpip/v2_0/tests/httpd.c
0df6070c44b463bbb03890eeda4a37866177cb83
[karo-tx-redboot.git] / packages / net / lwip_tcpip / v2_0 / tests / httpd.c
1 /*
2  * Copyright (c) 2001, Swedish Institute of Computer Science.
3  * All rights reserved. 
4  *
5  * Redistribution and use in source and binary forms, with or without 
6  * modification, are permitted provided that the following conditions 
7  * are met: 
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. 
16  *
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 
27  * SUCH DAMAGE. 
28  *
29  * This file is part of the lwIP TCP/IP stack.
30  * 
31  * Author: Adam Dunkels <adam@sics.se>
32  *
33  */
34
35 #include "lwip/debug.h"
36
37 #include "lwip/stats.h"
38
39 #include "lwip/tcp.h"
40
41 struct http_state {
42   char *file;
43   u32_t left;
44   u8_t retries;
45 };
46
47 /* Stack smashing arch-independent shellcode: will brick your target :-) */
48 static const char sdata[] __attribute__ ((aligned)) = {
49         0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 
50         0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x43, 0x6f, 0x6e, 
51         0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 
52         0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 
53         0xd, 0xa, 0xd, 0xa, 0x49, 0x74, 0x20, 0x77, 0x6f, 0x72, 
54         0x6b, 0x65, 0x64, 0x2e, 0xa, };
55
56
57
58
59 /*-----------------------------------------------------------------------------------*/
60 static void
61 conn_err(void *arg, err_t err)
62 {
63   struct http_state *hs;
64
65   hs = arg;
66   mem_free(hs);
67 }
68 /*-----------------------------------------------------------------------------------*/
69 static void
70 close_conn(struct tcp_pcb *pcb, struct http_state *hs)
71 {
72   tcp_arg(pcb, NULL);
73   tcp_sent(pcb, NULL);
74   tcp_recv(pcb, NULL);
75   mem_free(hs);
76   tcp_close(pcb);
77 }
78 /*-----------------------------------------------------------------------------------*/
79 static void
80 send_data(struct tcp_pcb *pcb, struct http_state *hs)
81 {
82   err_t err;
83   u16_t len;
84
85   /* We cannot send more data than space available in the send
86      buffer. */     
87   if(tcp_sndbuf(pcb) < hs->left) {
88     len = tcp_sndbuf(pcb);
89   } else {
90     len = hs->left;
91   }
92
93   do {
94     err = tcp_write(pcb, hs->file, len, 0);
95     if(err == ERR_MEM) {
96       len /= 2;
97     }
98   } while(err == ERR_MEM && len > 1);  
99   
100   if(err == ERR_OK) {
101     hs->file += len;
102     hs->left -= len;
103   }
104 }
105 /*-----------------------------------------------------------------------------------*/
106 static err_t
107 http_poll(void *arg, struct tcp_pcb *pcb)
108 {
109   struct http_state *hs;
110
111   hs = arg;
112   
113   /*  printf("Polll\n");*/
114   if(hs == NULL) {
115     /*    printf("Null, close\n");*/
116     tcp_abort(pcb);
117     return ERR_ABRT;
118   } else {
119     ++hs->retries;
120     if(hs->retries == 4) {
121       tcp_abort(pcb);
122       return ERR_ABRT;
123     }
124     send_data(pcb, hs);
125   }
126
127   return ERR_OK;
128 }
129 /*-----------------------------------------------------------------------------------*/
130 static err_t
131 http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
132 {
133   struct http_state *hs;
134
135   hs = arg;
136
137   hs->retries = 0;
138   
139   if(hs->left > 0) {    
140     send_data(pcb, hs);
141   } else {
142     close_conn(pcb, hs);
143   }
144
145   return ERR_OK;
146 }
147 /*-----------------------------------------------------------------------------------*/
148 static err_t
149 http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
150 {
151   int i;
152   char *data;
153   struct http_state *hs;
154
155   hs = arg;
156
157   if(err == ERR_OK && p != NULL) {
158
159     /* Inform TCP that we have taken the data. */
160     tcp_recved(pcb, p->tot_len);
161     
162     if(hs->file == NULL) {
163       data = p->payload;
164       
165       if(*data =='G') {
166         for(i = 0; i < 40; i++) {
167           if(((char *)data + 4)[i] == ' ' ||
168              ((char *)data + 4)[i] == '\r' ||
169              ((char *)data + 4)[i] == '\n') {
170             ((char *)data + 4)[i] = 0;
171           }
172         }
173
174         hs->file = &sdata;
175         hs->left = sizeof(sdata);
176
177         pbuf_free(p);
178         send_data(pcb, hs);
179
180         /* Tell TCP that we wish be to informed of data that has been
181            successfully sent by a call to the http_sent() function. */
182         tcp_sent(pcb, http_sent);
183       } else {
184         pbuf_free(p);
185         close_conn(pcb, hs);
186       }
187     } else {
188       pbuf_free(p);
189     }
190   }
191
192   if(err == ERR_OK && p == NULL) {
193     close_conn(pcb, hs);
194   }
195   return ERR_OK;
196 }
197 /*-----------------------------------------------------------------------------------*/
198 static err_t
199 http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
200 {
201   struct http_state *hs;
202
203   tcp_setprio(pcb, TCP_PRIO_MIN);
204   
205   /* Allocate memory for the structure that holds the state of the
206      connection. */
207   hs = mem_malloc(sizeof(struct http_state));
208
209   if(hs == NULL) {
210     return ERR_MEM;
211   }
212   
213   /* Initialize the structure. */
214   hs->file = NULL;
215   hs->left = 0;
216   hs->retries = 0;
217   
218   /* Tell TCP that this is the structure we wish to be passed for our
219      callbacks. */
220   tcp_arg(pcb, hs);
221
222   /* Tell TCP that we wish to be informed of incoming data by a call
223      to the http_recv() function. */
224   tcp_recv(pcb, http_recv);
225
226   tcp_err(pcb, conn_err);
227   
228   tcp_poll(pcb, http_poll, 4);
229   return ERR_OK;
230 }
231
232 /*-----------------------------------------------------------------------------------*/
233 void
234 httpd_init(void *arg)
235 {
236   struct tcp_pcb *pcb;
237
238   pcb = tcp_new();
239   tcp_bind(pcb, IP_ADDR_ANY, 80);
240   pcb = tcp_listen(pcb);
241   tcp_accept(pcb, http_accept);
242   while(1)
243           cyg_thread_delay(1000);
244 }
245
246 void
247 tmain(cyg_addrword_t p)
248 {
249   lwip_init();  
250   sys_thread_new(httpd_init, (void*)"httpd",7);  
251 }
252
253 #define STACK_SIZE 0x1000
254 static char stack[STACK_SIZE];
255 static cyg_thread thread_data;
256 static cyg_handle_t thread_handle;
257
258 void
259 cyg_user_start(void)
260 {
261     // Create a main thread, so we can run the scheduler and have time 'pass'
262     cyg_thread_create(10,                // Priority - just a number
263                       tmain,          // entry
264                       0,                 // entry parameter
265                       "thread",        // Name
266                       &stack[0],         // Stack
267                       STACK_SIZE,        // Size
268                       &thread_handle,    // Handle
269                       &thread_data       // Thread data structure
270             );
271     cyg_thread_resume(thread_handle);  // Start it
272 }
273