f9a81e90c67645b4ccc8beb211b107e0141e768f
[openwrt/staging/florian.git] / package / uboot-lantiq / patches / 300-httpd.patch
1 --- a/common/cmd_net.c
2 +++ b/common/cmd_net.c
3 @@ -43,6 +43,18 @@ U_BOOT_CMD(
4 "[loadAddress] [[hostIPaddr:]bootfilename]"
5 );
6
7 +#if defined(CONFIG_CMD_HTTPD)
8 +int do_httpd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
9 +{
10 + return NetLoopHttpd();
11 +}
12 +
13 +U_BOOT_CMD(
14 + httpd, 1, 1, do_httpd,
15 + "httpd\t- start webserver\n", "\n"
16 +);
17 +#endif
18 +
19 int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
20 {
21 return netboot_common (TFTP, cmdtp, argc, argv);
22 --- a/include/net.h
23 +++ b/include/net.h
24 @@ -383,7 +383,8 @@ extern int NetTimeOffset; /* offset ti
25
26 /* Initialize the network adapter */
27 extern int NetLoop(proto_t);
28 -
29 +extern int NetLoopHttpd(void);
30 +extern void NetSendHttpd(void);
31 /* Shutdown adapters and cleanup */
32 extern void NetStop(void);
33
34 --- /dev/null
35 +++ b/net/httpd.c
36 @@ -0,0 +1,52 @@
37 +/*
38 + * Copyright 1994, 1995, 2000 Neil Russell.
39 + * (See License)
40 + * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
41 + */
42 +
43 +#include <common.h>
44 +#include <command.h>
45 +#include <net.h>
46 +#include "uip-0.9/uipopt.h"
47 +#include "uip-0.9/uip.h"
48 +#include "uip-0.9/uip_arp.h"
49 +
50 +
51 +#if defined(CONFIG_CMD_HTTPD)
52 +
53 +#define TIMEOUT 5
54 +
55 +static int arptimer = 0;
56 +
57 +void
58 +HttpdHandler (void)
59 +{
60 + int i;
61 + for(i = 0; i < UIP_CONNS; i++) {
62 + uip_periodic(i);
63 + if(uip_len > 0) {
64 + uip_arp_out();
65 + NetSendHttpd();
66 + }
67 + }
68 + if(++arptimer == 20) {
69 + uip_arp_timer();
70 + arptimer = 0;
71 + }
72 +}
73 +
74 +static void
75 +HttpdTimeout (void)
76 +{
77 + puts ("T ");
78 + NetSetTimeout (TIMEOUT * 1000, HttpdTimeout);
79 +}
80 +
81 +void
82 +HttpdStart (void)
83 +{
84 + uip_init();
85 + httpd_init();
86 +}
87 +
88 +#endif
89 --- /dev/null
90 +++ b/include/httpd.h
91 @@ -0,0 +1,17 @@
92 +#ifndef _UIP_HTTPD_H__
93 +#define _UIP_HTTPD_H__
94 +
95 +void HttpdStart (void);
96 +void HttpdHandler (void);
97 +
98 +/* board specific implementation */
99 +extern int do_http_upgrade(const unsigned char *data, const ulong size);
100 +
101 +#define HTTP_PROGRESS_START 0
102 +#define HTTP_PROGRESS_TIMEOUT 1
103 +#define HTTP_PROGRESS_UPLOAD_READY 2
104 +#define HTTP_PROGRESS_UGRADE_READY 3
105 +#define HTTP_PROGRESS_UGRADE_FAILED 4
106 +extern int do_http_progress(const int state);
107 +
108 +#endif
109 --- a/net/Makefile
110 +++ b/net/Makefile
111 @@ -26,6 +26,10 @@ include $(TOPDIR)/config.mk
112 # CFLAGS += -DDEBUG
113
114 LIB = $(obj)libnet.a
115 +UIPDIR = uip-0.9
116 +RSADIR = uip-0.9
117 +$(shell mkdir -p $(obj)$(UIPDIR))
118 +$(shell mkdir -p $(obj)$(RSADIR))
119
120 COBJS-y += bootp.o
121 COBJS-$(CONFIG_CMD_DNS) += dns.o
122 @@ -36,6 +40,9 @@ COBJS-y += rarp.o
123 COBJS-$(CONFIG_CMD_SNTP) += sntp.o
124 COBJS-y += tftp.o
125
126 +COBJS-$(CONFIG_CMD_HTTPD) += httpd.o $(UIPDIR)/fs.o $(UIPDIR)/httpd.o $(UIPDIR)/uip_arp.o $(UIPDIR)/uip_arch.o $(UIPDIR)/uip.o
127 +COBJS-$(CONFIG_CMD_RSA) += $(RSADIR)/bigint.o $(RSADIR)/base64.o $(RSADIR)/rmd160.o $(RSADIR)/rsa.o
128 +
129 COBJS := $(COBJS-y)
130 SRCS := $(COBJS:.o=.c)
131 OBJS := $(addprefix $(obj),$(COBJS))
132 --- a/net/net.c
133 +++ b/net/net.c
134 @@ -95,6 +95,19 @@
135 #if defined(CONFIG_CMD_DNS)
136 #include "dns.h"
137 #endif
138 +#if defined(CONFIG_CMD_HTTPD)
139 +#include "httpd.h"
140 +#include "uip-0.9/uipopt.h"
141 +#include "uip-0.9/uip.h"
142 +#include "uip-0.9/uip_arp.h"
143 +static int https_running = 0;
144 +int httpd_upload_complete = 0;
145 +unsigned char *httpd_upload_data = 0;
146 +extern int upload_running;
147 +void NetReceiveHttpd(volatile uchar * inpkt, int len);
148 +void NetSendHttpd(void);
149 +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
150 +#endif
151
152 #if defined(CONFIG_CMD_NET)
153
154 @@ -1310,6 +1323,13 @@ NetReceive(volatile uchar * inpkt, int l
155
156 debug("packet received\n");
157
158 +#if defined(CONFIG_CMD_HTTPD)
159 + if(https_running) {
160 + NetReceiveHttpd(inpkt, len);
161 + return;
162 + }
163 +#endif
164 +
165 NetRxPacket = inpkt;
166 NetRxPacketLen = len;
167 et = (Ethernet_t *)inpkt;
168 @@ -1952,3 +1972,161 @@ ushort getenv_VLAN(char *var)
169 {
170 return (string_to_VLAN(getenv(var)));
171 }
172 +
173 +#if defined(CONFIG_CMD_HTTPD)
174 +
175 +void
176 +NetSendHttpd(void)
177 +{
178 + volatile uchar *tmpbuf = NetTxPacket;
179 + int i;
180 +
181 + for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
182 + tmpbuf[i] = uip_buf[i];
183 + }
184 +
185 + for(; i < uip_len; i++) {
186 + tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
187 + }
188 + eth_send(NetTxPacket, uip_len);
189 +}
190 +
191 +#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
192 +
193 +void
194 +NetReceiveHttpd(volatile uchar * inpkt, int len)
195 +{
196 + memcpy(uip_buf, inpkt, len);
197 + uip_len = len;
198 + if(BUF->type == htons(UIP_ETHTYPE_IP)) {
199 + uip_arp_ipin();
200 + uip_input();
201 + if(uip_len > 0) {
202 + uip_arp_out();
203 + NetSendHttpd();
204 + }
205 + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
206 + uip_arp_arpin();
207 + if(uip_len > 0) {
208 + NetSendHttpd();
209 + }
210 + }
211 +}
212 +
213 +int
214 +NetLoopHttpd(void)
215 +{
216 + unsigned long long tout = 0;
217 + bd_t *bd = gd->bd;
218 + unsigned short int ip[2];
219 +
220 +#ifdef CONFIG_NET_MULTI
221 + NetRestarted = 0;
222 + NetDevExists = 0;
223 +#endif
224 +
225 + /* XXX problem with bss workaround */
226 + NetArpWaitPacketMAC = NULL;
227 + NetArpWaitTxPacket = NULL;
228 + NetArpWaitPacketIP = 0;
229 + NetArpWaitReplyIP = 0;
230 + NetArpWaitTxPacket = NULL;
231 + NetTxPacket = NULL;
232 + NetTryCount = 1;
233 +
234 + if (!NetTxPacket) {
235 + int i;
236 + /*
237 + * Setup packet buffers, aligned correctly.
238 + */
239 + NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
240 + NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
241 + for (i = 0; i < PKTBUFSRX; i++) {
242 + NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;
243 + }
244 + }
245 +
246 + if (!NetArpWaitTxPacket) {
247 + NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
248 + NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
249 + NetArpWaitTxPacketSize = 0;
250 + }
251 +
252 + eth_halt();
253 +#ifdef CONFIG_NET_MULTI
254 + eth_set_current();
255 +#endif
256 + if (eth_init(bd) < 0) {
257 + eth_halt();
258 + return(-1);
259 + }
260 +
261 +restart:
262 +#ifdef CONFIG_NET_MULTI
263 + memcpy (NetOurEther, eth_get_dev()->enetaddr, 6);
264 +#else
265 + eth_getenv_enetaddr("ethaddr", NetOurEther);
266 +#endif
267 +
268 + NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
269 + NetOurGatewayIP = getenv_IPaddr ("gatewayip");
270 + NetOurSubnetMask= getenv_IPaddr ("netmask");
271 + NetOurVLAN = getenv_VLAN("vlan");
272 + NetOurNativeVLAN = getenv_VLAN("nvlan");
273 +
274 + printf("starting httpd server from server %ld.%ld.%ld.%ld\n",
275 + (bd->bi_ip_addr & 0xff000000) >> 24,
276 + (bd->bi_ip_addr & 0x00ff0000) >> 16,
277 + (bd->bi_ip_addr & 0x0000ff00) >> 8,
278 + (bd->bi_ip_addr & 0x000000ff));
279 +
280 + HttpdStart();
281 +
282 + ip[0] = ((bd->bi_ip_addr & 0xffff0000) >> 16);
283 + ip[1] = (bd->bi_ip_addr & 0x0000ffff);
284 + uip_sethostaddr(ip);
285 +
286 + do_http_progress(HTTP_PROGRESS_START);
287 +
288 + https_running = 1;
289 + for (;;) {
290 + unsigned long long t1;
291 + WATCHDOG_RESET();
292 + if(eth_rx() > 0) {
293 + HttpdHandler();
294 + } else {
295 + t1 = get_ticks();
296 + if(t1 - tout > 1000) {
297 + do_http_progress(HTTP_PROGRESS_TIMEOUT);
298 + tout = t1;
299 + }
300 + }
301 + if(!httpd_upload_complete)
302 + continue;
303 + printf("Bytes transferred = %ld (%lx hex)\n",
304 + NetBootFileXferSize,
305 + NetBootFileXferSize);
306 + eth_halt();
307 + do_http_progress(HTTP_PROGRESS_UPLOAD_READY);
308 + if(do_http_upgrade(&httpd_upload_data[0], NetBootFileXferSize) == 0) {
309 + do_http_progress(HTTP_PROGRESS_UGRADE_READY);
310 + udelay(1000 * 10);
311 + do_reset (0,0,0,0);
312 + return 0;
313 + }
314 + break;
315 + }
316 + https_running = 0;
317 + NetBootFileXferSize = 0;
318 + httpd_upload_complete = 0;
319 + upload_running = 0;
320 +// free(httpd_upload_data);
321 +
322 + do_http_progress(HTTP_PROGRESS_UGRADE_FAILED);
323 +
324 + goto restart;
325 +
326 + return -1;
327 +}
328 +
329 +#endif
330 --- /dev/null
331 +++ b/net/rsa/base64.c
332 @@ -0,0 +1,137 @@
333 +#include "base64.h"
334 +
335 +static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
336 +/* Note that '=' (padding) is 0 */
337 +static const unsigned char fb64[256] = {
338 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
339 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
340 + 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
341 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
342 + 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
343 + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
344 + 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
345 + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
346 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
347 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
348 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
349 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
350 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
351 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
352 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
353 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
354 +};
355 +
356 +static int encodeblock( unsigned char *in, char *out, int len )
357 +{
358 + char s[3];
359 + int i;
360 +
361 + for (i = 0; i < len; i++)
362 + s[i] = in[i];
363 + for (i = len; i < 3; i++)
364 + s[i] = 0;
365 + out[0] = (unsigned char)(cb64[(s[0] & 0xfc) >> 2 ]);
366 + out[1] = (unsigned char)(cb64[((s[0] & 0x03) << 4) | ((s[1] & 0xf0) >> 4) ]);
367 + out[2] = (unsigned char)(cb64[((s[1] & 0x0f) << 2) | ((s[2] & 0xc0) >> 6) ]);
368 + out[3] = (unsigned char)(cb64[s[2] & 0x3f ]);
369 + switch (len) {
370 + case 1:
371 + out[3] = '=';
372 + case 2:
373 + out[2] = '=';
374 + break;
375 + default:
376 + break;
377 + }
378 +
379 + return 4;
380 +}
381 +
382 +static int decodeblock(char *ins, unsigned char *out, int len)
383 +{
384 + int i;
385 + unsigned char in[4];
386 + int skip = 0;
387 +
388 + if (len != 4)
389 + return -1;
390 + for (i = 0; i < len; i++) {
391 + if (ins[i] == '=') {
392 + in[i] = 0;
393 + skip++;
394 + } else
395 + in[i] = fb64[(int)(ins[i])];
396 + if (in[i] == 255) {
397 + return -1;
398 + }
399 + }
400 + out[0] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
401 + if (skip == 2) {
402 + return 1;
403 + }
404 + out[1] = (unsigned char )((in[1] & 0x0f) << 4 | in[2] >> 2);
405 + if (skip == 1) {
406 + return 2;
407 + }
408 + out[2] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
409 +
410 + return 3;
411 +}
412 +
413 +int B64_encode(char *source, char *destination, int size_source, int size_destination)
414 +{
415 + int chunks, reminder, size, d, i, size_expected;
416 + char *s;
417 + unsigned char *t;
418 +
419 + chunks = size_source / 3;
420 + reminder = size_source % 3;
421 + size = 0;
422 + size_expected = (chunks * 4) + (reminder?(reminder + 1):0);
423 + if (size_destination < ((chunks * 4) + (reminder?4:0))) {
424 + return 1;
425 + }
426 + for (i = 0; i < chunks; i++) {
427 + s = source + (i * 3);
428 + t = destination + (i * 4);
429 + d = encodeblock(s, t, 3);
430 + if (d == -1) {
431 + return 1;
432 + }
433 + size += d;
434 + }
435 + if (reminder) {
436 + d = encodeblock(source + (chunks * 3), destination + (chunks * 4), reminder);
437 + if (d == -1) {
438 + return 1;
439 + }
440 + size += d;
441 + }
442 + return size;
443 +}
444 +
445 +int B64_decode(char *source, char *destination, int size_source, int size_destination)
446 +{
447 + int chunks, reminder, size, d, i;
448 +
449 + chunks = size_source / 4;
450 + reminder = size_source % 4;
451 + size = 0;
452 + if (reminder) {
453 + return 1;
454 + }
455 + if (size_destination < ((chunks * 3))) {
456 + printf("%d, %d\n",
457 + size_destination, ((chunks * 3) + reminder));
458 + return -1;
459 + }
460 + for (i = 0; i < chunks; i++) {
461 + d = decodeblock(source + (i * 4), destination + (i * 3), 4);
462 + if (d == -1) {
463 + return -1;
464 + }
465 + size += d;
466 + }
467 + return size;
468 +}
469 +
470 --- /dev/null
471 +++ b/net/rsa/base64.h
472 @@ -0,0 +1,11 @@
473 +#ifndef _BASE64_H_
474 +#define _BASE64_H_
475 +#ifdef __cplusplus
476 +extern "C" {
477 +#endif
478 +int B64_encode(char *source, char *destination, int size_source, int size_destination);
479 +int B64_decode(char *source, char *destination, int size_source, int size_destination);
480 +#ifdef __cplusplus
481 +}
482 +#endif
483 +#endif
484 --- /dev/null
485 +++ b/net/rsa/bigint.c
486 @@ -0,0 +1,906 @@
487 +/*
488 + * Copyright(C) 2006
489 + *
490 + * This library is free software; you can redistribute it and/or modify
491 + * it under the terms of the GNU Lesser General Public License as published by
492 + * the Free Software Foundation; either version 2.1 of the License, or
493 + * (at your option) any later version.
494 + *
495 + * This library is distributed in the hope that it will be useful,
496 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
497 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
498 + * GNU Lesser General Public License for more details.
499 + *
500 + * You should have received a copy of the GNU Lesser General Public License
501 + * along with this library; if not, write to the Free Software
502 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
503 + */
504 +
505 +/**
506 + * @defgroup bigint_api Big Integer API
507 + * @brief The bigint implementation as used by the axTLS project.
508 + *
509 + * The bigint library is for RSA encryption/decryption as well as signing.
510 + * This code tries to minimise use of malloc/free by maintaining a small
511 + * cache. A bigint context may maintain state by being made "permanent".
512 + * It be be later released with a bi_depermanent() and bi_free() call.
513 + *
514 + * It supports the following reduction techniques:
515 + * - Classical
516 + * - Barrett
517 + * - Montgomery
518 + *
519 + * It also implements the following:
520 + * - Karatsuba multiplication
521 + * - Squaring
522 + * - Sliding window exponentiation
523 + * - Chinese Remainder Theorem (implemented in rsa.c).
524 + *
525 + * All the algorithms used are pretty standard, and designed for different
526 + * data bus sizes. Negative numbers are not dealt with at all, so a subtraction
527 + * may need to be tested for negativity.
528 + *
529 + * This library steals some ideas from Jef Poskanzer
530 + * <http://cs.marlboro.edu/term/cs-fall02/algorithms/crypto/RSA/bigint>
531 + * and GMP <http://www.swox.com/gmp>. It gets most of its implementation
532 + * detail from "The Handbook of Applied Cryptography"
533 + * <http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf>
534 + * @{
535 + */
536 +
537 +#include "bigint.h"
538 +#include <malloc.h>
539 +#include "div64.h"
540 +
541 +static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bi, comp i);
542 +static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom);
543 +static bigint *alloc(BI_CTX *ctx, int size);
544 +static bigint *trim(bigint *bi);
545 +static void more_comps(bigint *bi, int n);
546 +
547 +/**
548 + * @brief Start a new bigint context.
549 + * @return A bigint context.
550 + */
551 +BI_CTX *bi_initialize(void)
552 +{
553 + BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX));
554 +
555 + ctx->active_list = NULL;
556 + ctx->active_count = 0;
557 + ctx->free_list = NULL;
558 + ctx->free_count = 0;
559 + ctx->mod_offset = 0;
560 +
561 + /* the radix */
562 + ctx->bi_radix = alloc(ctx, 2);
563 + ctx->bi_radix->comps[0] = 0;
564 + ctx->bi_radix->comps[1] = 1;
565 + bi_permanent(ctx->bi_radix);
566 +
567 + return ctx;
568 +}
569 +
570 +/**
571 + * @brief Close the bigint context and free any resources.
572 + *
573 + * Free up any used memory - a check is done if all objects were not
574 + * properly freed.
575 + * @param ctx [in] The bigint session context.
576 + */
577 +void bi_terminate(BI_CTX *ctx)
578 +{
579 + bigint *p, *pn;
580 +
581 + bi_depermanent(ctx->bi_radix);
582 + bi_free(ctx, ctx->bi_radix);
583 +
584 + if (ctx->active_count != 0)
585 + {
586 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
587 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
588 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
589 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
590 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
591 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
592 + return;
593 + }
594 +
595 + for (p = ctx->free_list; p != NULL; p = pn)
596 + {
597 + pn = p->next;
598 + free(p->comps);
599 + free(p);
600 + }
601 +
602 + free(ctx);
603 +}
604 +
605 +/**
606 + * @brief Increment the number of references to this object.
607 + * It does not do a full copy.
608 + * @param bi [in] The bigint to copy.
609 + * @return A referent to the same bigint.
610 + */
611 +bigint *bi_copy(bigint *bi)
612 +{
613 + check(bi);
614 + if (bi->refs != PERMANENT)
615 + bi->refs++;
616 + return bi;
617 +}
618 +
619 +/**
620 + * @brief Simply make a bigint object "unfreeable" if bi_free() is called on it.
621 + *
622 + * For this object to be freed, bi_depermanent() must be called.
623 + * @param bi [in] The bigint to be made permanent.
624 + */
625 +void bi_permanent(bigint *bi)
626 +{
627 + check(bi);
628 + if (bi->refs != 1)
629 + {
630 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
631 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
632 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
633 + return;
634 + }
635 +
636 + bi->refs = PERMANENT;
637 +}
638 +
639 +/**
640 + * @brief Take a permanent object and make it elligible for freedom.
641 + * @param bi [in] The bigint to be made back to temporary.
642 + */
643 +void bi_depermanent(bigint *bi)
644 +{
645 + check(bi);
646 + if (bi->refs != PERMANENT)
647 + {
648 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
649 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
650 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
651 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
652 + return;
653 + }
654 +
655 + bi->refs = 1;
656 +}
657 +
658 +/**
659 + * @brief Free a bigint object so it can be used again.
660 + *
661 + * The memory itself it not actually freed, just tagged as being available
662 + * @param ctx [in] The bigint session context.
663 + * @param bi [in] The bigint to be freed.
664 + */
665 +void bi_free(BI_CTX *ctx, bigint *bi)
666 +{
667 + check(bi);
668 + if (bi->refs == PERMANENT)
669 + {
670 + return;
671 + }
672 +
673 + if (--bi->refs > 0)
674 + {
675 + return;
676 + }
677 +
678 + bi->next = ctx->free_list;
679 + ctx->free_list = bi;
680 + ctx->free_count++;
681 +
682 + if (--ctx->active_count < 0)
683 + {
684 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
685 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
686 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
687 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
688 + return;
689 + }
690 +}
691 +
692 +/**
693 + * @brief Convert an (unsigned) integer into a bigint.
694 + * @param ctx [in] The bigint session context.
695 + * @param i [in] The (unsigned) integer to be converted.
696 + *
697 + */
698 +bigint *int_to_bi(BI_CTX *ctx, comp i)
699 +{
700 + bigint *biR = alloc(ctx, 1);
701 + biR->comps[0] = i;
702 + return biR;
703 +}
704 +
705 +/**
706 + * @brief Do a full copy of the bigint object.
707 + * @param ctx [in] The bigint session context.
708 + * @param bi [in] The bigint object to be copied.
709 + */
710 +bigint *bi_clone(BI_CTX *ctx, const bigint *bi)
711 +{
712 + bigint *biR = alloc(ctx, bi->size);
713 + check(bi);
714 + memcpy(biR->comps, bi->comps, bi->size*COMP_BYTE_SIZE);
715 + return biR;
716 +}
717 +
718 +/**
719 + * @brief Perform an additon operation between two bigints.
720 + * @param ctx [in] The bigint session context.
721 + * @param bia [in] A bigint.
722 + * @param bib [in] Another bigint.
723 + * @return The result of the addition.
724 + */
725 +bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib)
726 +{
727 + int n;
728 + comp carry = 0;
729 + comp *pa, *pb;
730 +
731 + check(bia);
732 + check(bib);
733 +
734 + if (bia->size > bib->size)
735 + n = bia->size;
736 + else
737 + n = bib->size;
738 + more_comps(bia, n+1);
739 + more_comps(bib, n);
740 + pa = bia->comps;
741 + pb = bib->comps;
742 +
743 + do
744 + {
745 + comp sl, rl, cy1;
746 + sl = *pa + *pb++;
747 + rl = sl + carry;
748 + cy1 = sl < *pa;
749 + carry = cy1 | (rl < sl);
750 + *pa++ = rl;
751 + } while (--n != 0);
752 +
753 + *pa = carry; /* do overflow */
754 + bi_free(ctx, bib);
755 + return trim(bia);
756 +}
757 +
758 +/**
759 + * @brief Perform a subtraction operation between two bigints.
760 + * @param ctx [in] The bigint session context.
761 + * @param bia [in] A bigint.
762 + * @param bib [in] Another bigint.
763 + * @param is_negative [out] If defined, indicates that the result was negative.
764 + * is_negative may be NULL.
765 + * @return The result of the subtraction. The result is always positive.
766 + */
767 +bigint *bi_subtract(BI_CTX *ctx,
768 + bigint *bia, bigint *bib, int *is_negative)
769 +{
770 + int n = bia->size;
771 + comp *pa, *pb, carry = 0;
772 +
773 + check(bia);
774 + check(bib);
775 +
776 + more_comps(bib, n);
777 + pa = bia->comps;
778 + pb = bib->comps;
779 +
780 + do
781 + {
782 + comp sl, rl, cy1;
783 + sl = *pa - *pb++;
784 + rl = sl - carry;
785 + cy1 = sl > *pa;
786 + carry = cy1 | (rl > sl);
787 + *pa++ = rl;
788 + } while (--n != 0);
789 +
790 + if (is_negative) /* indicate a negative result */
791 + {
792 + *is_negative = carry;
793 + }
794 +
795 + bi_free(ctx, trim(bib)); /* put bib back to the way it was */
796 + return trim(bia);
797 +}
798 +
799 +/**
800 + * Perform a multiply between a bigint an an (unsigned) integer
801 + */
802 +static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b)
803 +{
804 + int j = 0, n = bia->size;
805 + bigint *biR = alloc(ctx, n + 1);
806 + comp carry = 0;
807 + comp *r = biR->comps;
808 + comp *a = bia->comps;
809 +
810 + check(bia);
811 +
812 + /* clear things to start with */
813 + memset(r, 0, ((n+1)*COMP_BYTE_SIZE));
814 +
815 + do
816 + {
817 + long_comp tmp = *r + (long_comp)a[j]*b + carry;
818 + *r++ = (comp)tmp; /* downsize */
819 + carry = (comp)(tmp >> COMP_BIT_SIZE);
820 + } while (++j < n);
821 +
822 + *r = carry;
823 + bi_free(ctx, bia);
824 + return trim(biR);
825 +}
826 +
827 +/**
828 + * @brief Does both division and modulo calculations.
829 + *
830 + * Used extensively when doing classical reduction.
831 + * @param ctx [in] The bigint session context.
832 + * @param u [in] A bigint which is the numerator.
833 + * @param v [in] Either the denominator or the modulus depending on the mode.
834 + * @param is_mod [n] Determines if this is a normal division (0) or a reduction
835 + * (1).
836 + * @return The result of the division/reduction.
837 + */
838 +bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
839 +{
840 + int n = v->size, m = u->size-n;
841 + int j = 0, orig_u_size = u->size;
842 + uint8_t mod_offset = ctx->mod_offset;
843 + comp d;
844 + bigint *quotient, *tmp_u;
845 + comp q_dash;
846 +
847 + check(u);
848 + check(v);
849 +
850 + /* if doing reduction and we are < mod, then return mod */
851 + if (is_mod && bi_compare(v, u) > 0)
852 + {
853 + bi_free(ctx, v);
854 + return u;
855 + }
856 +
857 + quotient = alloc(ctx, m+1);
858 + tmp_u = alloc(ctx, n+1);
859 + v = trim(v); /* make sure we have no leading 0's */
860 + // d = (comp)((long_comp)COMP_RADIX/(V1+1));
861 + long_comp x = COMP_RADIX; do_div(x, V1+1); d = x;
862 +
863 + /* clear things to start with */
864 + memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE));
865 +
866 + /* normalise */
867 + if (d > 1)
868 + {
869 + u = bi_int_multiply(ctx, u, d);
870 +
871 + if (is_mod)
872 + {
873 + v = ctx->bi_normalised_mod[mod_offset];
874 + }
875 + else
876 + {
877 + v = bi_int_multiply(ctx, v, d);
878 + }
879 + }
880 +
881 + if (orig_u_size == u->size) /* new digit position u0 */
882 + {
883 + more_comps(u, orig_u_size + 1);
884 + }
885 +
886 + do
887 + {
888 + /* get a temporary short version of u */
889 + memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE);
890 +
891 + /* calculate q' */
892 + if (U(0) == V1)
893 + {
894 + q_dash = COMP_RADIX-1;
895 + }
896 + else
897 + {
898 + //q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1);
899 + long_comp x = U(0)*COMP_RADIX + U(1); do_div(x, V1); q_dash = x;
900 +
901 + }
902 +
903 + if (v->size > 1 && V2)
904 + {
905 + /* we are implementing the following
906 + if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) -
907 + q_dash*V1)*COMP_RADIX) + U(2))) ... */
908 + comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) -
909 + (long_comp)q_dash*V1);
910 + if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2))
911 + {
912 + q_dash--;
913 + }
914 + }
915 +
916 + /* multiply and subtract */
917 + if (q_dash)
918 + {
919 + int is_negative;
920 + tmp_u = bi_subtract(ctx, tmp_u,
921 + bi_int_multiply(ctx, bi_copy(v), q_dash), &is_negative);
922 + more_comps(tmp_u, n+1);
923 +
924 + Q(j) = q_dash;
925 +
926 + /* add back */
927 + if (is_negative)
928 + {
929 + Q(j)--;
930 + tmp_u = bi_add(ctx, tmp_u, bi_copy(v));
931 + /* lop off the carry */
932 + tmp_u->size--;
933 + v->size--;
934 + }
935 + }
936 + else
937 + {
938 + Q(j) = 0;
939 + }
940 +
941 + /* copy back to u */
942 + memcpy(&u->comps[u->size-n-1-j], tmp_u->comps, (n+1)*COMP_BYTE_SIZE);
943 + } while (++j <= m);
944 +
945 + bi_free(ctx, tmp_u);
946 + bi_free(ctx, v);
947 +
948 + if (is_mod) /* get the remainder */
949 + {
950 + bi_free(ctx, quotient);
951 + return bi_int_divide(ctx, trim(u), d);
952 + }
953 + else /* get the quotient */
954 + {
955 + bi_free(ctx, u);
956 + return trim(quotient);
957 + }
958 +}
959 +
960 +/**
961 + * Perform an integer divide on a bigint.
962 + */
963 +static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom)
964 +{
965 + int i = biR->size - 1;
966 + long_comp r = 0;
967 +
968 + check(biR);
969 +
970 + do
971 + {
972 + r = (r<<COMP_BIT_SIZE) + biR->comps[i];
973 + //biR->comps[i] = (comp)(r / denom);
974 + long_comp x = r; do_div(x, denom); biR->comps[i] = x;
975 +/* while(r > denom)
976 + {
977 + r -= denom;
978 + }*/
979 + r%=denom;
980 + } while (--i != 0);
981 +
982 + return trim(biR);
983 +}
984 +
985 +/**
986 + * @brief Allow a binary sequence to be imported as a bigint.
987 + * @param ctx [in] The bigint session context.
988 + * @param data [in] The data to be converted.
989 + * @param size [in] The number of bytes of data.
990 + * @return A bigint representing this data.
991 + */
992 +bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int size)
993 +{
994 + bigint *biR = alloc(ctx, (size+COMP_BYTE_SIZE-1)/COMP_BYTE_SIZE);
995 + int i, j = 0, offset = 0;
996 +
997 + memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
998 +
999 + for (i = size-1; i >= 0; i--)
1000 + {
1001 + biR->comps[offset] += data[i] << (j*8);
1002 +
1003 + if (++j == COMP_BYTE_SIZE)
1004 + {
1005 + j = 0;
1006 + offset ++;
1007 + }
1008 + }
1009 +
1010 + return trim(biR);
1011 +}
1012 +
1013 +/**
1014 + * @brief Take a bigint and convert it into a byte sequence.
1015 + *
1016 + * This is useful after a decrypt operation.
1017 + * @param ctx [in] The bigint session context.
1018 + * @param x [in] The bigint to be converted.
1019 + * @param data [out] The converted data as a byte stream.
1020 + * @param size [in] The maximum size of the byte stream. Unused bytes will be
1021 + * zeroed.
1022 + */
1023 +void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
1024 +{
1025 + int i, j, k = size-1;
1026 +
1027 + check(x);
1028 + memset(data, 0, size); /* ensure all leading 0's are cleared */
1029 +
1030 + for (i = 0; i < x->size; i++)
1031 + {
1032 + for (j = 0; j < COMP_BYTE_SIZE; j++)
1033 + {
1034 + comp mask = 0xff << (j*8);
1035 + int num = (x->comps[i] & mask) >> (j*8);
1036 + data[k--] = num;
1037 +
1038 + if (k < 0)
1039 + {
1040 + break;
1041 + }
1042 + }
1043 + }
1044 +
1045 + bi_free(ctx, x);
1046 +}
1047 +
1048 +/**
1049 + * @brief Pre-calculate some of the expensive steps in reduction.
1050 + *
1051 + * This function should only be called once (normally when a session starts).
1052 + * When the session is over, bi_free_mod() should be called. bi_mod_power()
1053 + * relies on this function being called.
1054 + * @param ctx [in] The bigint session context.
1055 + * @param bim [in] The bigint modulus that will be used.
1056 + * @param mod_offset [in] There are three moduluii that can be stored - the
1057 + * standard modulus, and it's two primes p and q. This offset refers to which
1058 + * modulus we are referring to.
1059 + * @see bi_free_mod(), bi_mod_power().
1060 + */
1061 +void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset)
1062 +{
1063 + int k = bim->size;
1064 + comp d;
1065 +// comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1));
1066 + long_comp x = COMP_RADIX; do_div(x, bim->comps[k-1]+1); d = x;
1067 +
1068 + ctx->bi_mod[mod_offset] = bim;
1069 + bi_permanent(ctx->bi_mod[mod_offset]);
1070 + ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d);
1071 + bi_permanent(ctx->bi_normalised_mod[mod_offset]);
1072 +}
1073 +
1074 +/**
1075 + * @brief Used when cleaning various bigints at the end of a session.
1076 + * @param ctx [in] The bigint session context.
1077 + * @param mod_offset [in] The offset to use.
1078 + * @see bi_set_mod().
1079 + */
1080 +void bi_free_mod(BI_CTX *ctx, int mod_offset)
1081 +{
1082 + bi_depermanent(ctx->bi_mod[mod_offset]);
1083 + bi_free(ctx, ctx->bi_mod[mod_offset]);
1084 + bi_depermanent(ctx->bi_normalised_mod[mod_offset]);
1085 + bi_free(ctx, ctx->bi_normalised_mod[mod_offset]);
1086 +}
1087 +
1088 +/**
1089 + * Perform a standard multiplication between two bigints.
1090 + */
1091 +static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
1092 +{
1093 + int i, j, i_plus_j, n = bia->size, t = bib->size;
1094 + bigint *biR = alloc(ctx, n + t);
1095 + comp *sr = biR->comps;
1096 + comp *sa = bia->comps;
1097 + comp *sb = bib->comps;
1098 +
1099 + check(bia);
1100 + check(bib);
1101 +
1102 + /* clear things to start with */
1103 + memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE));
1104 + i = 0;
1105 +
1106 + do
1107 + {
1108 + comp carry = 0;
1109 + comp b = *sb++;
1110 + i_plus_j = i;
1111 + j = 0;
1112 +
1113 + do
1114 + {
1115 + long_comp tmp = sr[i_plus_j] + (long_comp)sa[j]*b + carry;
1116 + sr[i_plus_j++] = (comp)tmp; /* downsize */
1117 + carry = (comp)(tmp >> COMP_BIT_SIZE);
1118 + } while (++j < n);
1119 +
1120 + sr[i_plus_j] = carry;
1121 + } while (++i < t);
1122 +
1123 + bi_free(ctx, bia);
1124 + bi_free(ctx, bib);
1125 + return trim(biR);
1126 +}
1127 +
1128 +/**
1129 + * @brief Perform a multiplication operation between two bigints.
1130 + * @param ctx [in] The bigint session context.
1131 + * @param bia [in] A bigint.
1132 + * @param bib [in] Another bigint.
1133 + * @return The result of the multiplication.
1134 + */
1135 +bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
1136 +{
1137 + check(bia);
1138 + check(bib);
1139 +
1140 + return regular_multiply(ctx, bia, bib);
1141 +}
1142 +
1143 +
1144 +/**
1145 + * @brief Compare two bigints.
1146 + * @param bia [in] A bigint.
1147 + * @param bib [in] Another bigint.
1148 + * @return -1 if smaller, 1 if larger and 0 if equal.
1149 + */
1150 +int bi_compare(bigint *bia, bigint *bib)
1151 +{
1152 + int r, i;
1153 +
1154 + check(bia);
1155 + check(bib);
1156 +
1157 + if (bia->size > bib->size)
1158 + r = 1;
1159 + else if (bia->size < bib->size)
1160 + r = -1;
1161 + else
1162 + {
1163 + comp *a = bia->comps;
1164 + comp *b = bib->comps;
1165 +
1166 + /* Same number of components. Compare starting from the high end
1167 + * and working down. */
1168 + r = 0;
1169 + i = bia->size - 1;
1170 +
1171 + do
1172 + {
1173 + if (a[i] > b[i])
1174 + {
1175 + r = 1;
1176 + break;
1177 + }
1178 + else if (a[i] < b[i])
1179 + {
1180 + r = -1;
1181 + break;
1182 + }
1183 + } while (--i >= 0);
1184 + }
1185 +
1186 + return r;
1187 +}
1188 +
1189 +/**
1190 + * Allocate and zero more components. Does not consume bi.
1191 + */
1192 +static void more_comps(bigint *bi, int n)
1193 +{
1194 + if (n > bi->max_comps)
1195 + {
1196 + if ((bi->max_comps * 2) > n) {
1197 + bi->max_comps = bi->max_comps * 2;
1198 + } else {
1199 + bi->max_comps = n;
1200 + }
1201 + bi->comps = (comp*)realloc(bi->comps, bi->max_comps * COMP_BYTE_SIZE);
1202 + }
1203 +
1204 + if (n > bi->size)
1205 + {
1206 + memset(&bi->comps[bi->size], 0, (n-bi->size)*COMP_BYTE_SIZE);
1207 + }
1208 +
1209 + bi->size = n;
1210 +}
1211 +
1212 +/*
1213 + * Make a new empty bigint. It may just use an old one if one is available.
1214 + * Otherwise get one of the heap.
1215 + */
1216 +static bigint *alloc(BI_CTX *ctx, int size)
1217 +{
1218 + bigint *biR;
1219 +
1220 + /* Can we recycle an old bigint? */
1221 + if (ctx->free_list != NULL)
1222 + {
1223 + biR = ctx->free_list;
1224 + ctx->free_list = biR->next;
1225 + ctx->free_count--;
1226 + if (biR->refs != 0)
1227 + {
1228 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1229 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1230 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1231 + return 0;
1232 + }
1233 +
1234 + more_comps(biR, size);
1235 + }
1236 + else
1237 + {
1238 + /* No free bigints available - create a new one. */
1239 + biR = (bigint *)malloc(sizeof(bigint));
1240 + biR->comps = (comp*) malloc(size * COMP_BYTE_SIZE);
1241 + biR->max_comps = size; /* give some space to spare */
1242 + }
1243 +
1244 + biR->size = size;
1245 + biR->refs = 1;
1246 + biR->next = NULL;
1247 + ctx->active_count++;
1248 + return biR;
1249 +}
1250 +
1251 +/*
1252 + * Work out the highest '1' bit in an exponent. Used when doing sliding-window
1253 + * exponentiation.
1254 + */
1255 +static int find_max_exp_index(bigint *biexp)
1256 +{
1257 + int i = COMP_BIT_SIZE-1;
1258 + comp shift = COMP_RADIX/2;
1259 + comp test = biexp->comps[biexp->size-1]; /* assume no leading zeroes */
1260 +
1261 + check(biexp);
1262 +
1263 + do
1264 + {
1265 + if (test & shift)
1266 + {
1267 + return i+(biexp->size-1)*COMP_BIT_SIZE;
1268 + }
1269 +
1270 + shift >>= 1;
1271 + } while (--i != 0);
1272 +
1273 + return -1; /* error - must have been a leading 0 */
1274 +}
1275 +
1276 +/*
1277 + * Is a particular bit is an exponent 1 or 0? Used when doing sliding-window
1278 + * exponentiation.
1279 + */
1280 +static int exp_bit_is_one(bigint *biexp, int offset)
1281 +{
1282 + comp test = biexp->comps[offset / COMP_BIT_SIZE];
1283 + int num_shifts = offset % COMP_BIT_SIZE;
1284 + comp shift = 1;
1285 + int i;
1286 +
1287 + check(biexp);
1288 +
1289 + for (i = 0; i < num_shifts; i++)
1290 + {
1291 + shift <<= 1;
1292 + }
1293 +
1294 + return test & shift;
1295 +}
1296 +
1297 +/*
1298 + * Delete any leading 0's (and allow for 0).
1299 + */
1300 +static bigint *trim(bigint *bi)
1301 +{
1302 + check(bi);
1303 +
1304 + while (bi->comps[bi->size-1] == 0 && bi->size > 1)
1305 + {
1306 + bi->size--;
1307 + }
1308 +
1309 + return bi;
1310 +}
1311 +
1312 +/**
1313 + * @brief Perform a modular exponentiation.
1314 + *
1315 + * This function requires bi_set_mod() to have been called previously. This is
1316 + * one of the optimisations used for performance.
1317 + * @param ctx [in] The bigint session context.
1318 + * @param bi [in] The bigint on which to perform the mod power operation.
1319 + * @param biexp [in] The bigint exponent.
1320 + * @see bi_set_mod().
1321 + */
1322 +bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
1323 +{
1324 + int i = find_max_exp_index(biexp), j, window_size = 1;
1325 + bigint *biR = int_to_bi(ctx, 1);
1326 +
1327 + check(bi);
1328 + check(biexp);
1329 +
1330 + ctx->g = (bigint **)malloc(sizeof(bigint *));
1331 + ctx->g[0] = bi_clone(ctx, bi);
1332 + ctx->window = 1;
1333 + bi_permanent(ctx->g[0]);
1334 +
1335 + /* if sliding-window is off, then only one bit will be done at a time and
1336 + * will reduce to standard left-to-right exponentiation */
1337 + do
1338 + {
1339 + if (exp_bit_is_one(biexp, i))
1340 + {
1341 + int l = i-window_size+1;
1342 + int part_exp = 0;
1343 +
1344 + if (l < 0) /* LSB of exponent will always be 1 */
1345 + {
1346 + l = 0;
1347 + }
1348 + else
1349 + {
1350 + while (exp_bit_is_one(biexp, l) == 0)
1351 + {
1352 + l++; /* go back up */
1353 + }
1354 + }
1355 +
1356 + /* build up the section of the exponent */
1357 + for (j = i; j >= l; j--)
1358 + {
1359 + biR = bi_residue(ctx, bi_square(ctx, biR));
1360 + if (exp_bit_is_one(biexp, j))
1361 + part_exp++;
1362 +
1363 + if (j != l)
1364 + part_exp <<= 1;
1365 + }
1366 +
1367 + part_exp = (part_exp-1)/2; /* adjust for array */
1368 + biR = bi_residue(ctx,
1369 + bi_multiply(ctx, biR, ctx->g[part_exp]));
1370 + i = l-1;
1371 + }
1372 + else /* square it */
1373 + {
1374 + biR = bi_residue(ctx, bi_square(ctx, biR));
1375 + i--;
1376 + }
1377 + } while (i >= 0);
1378 +
1379 + /* cleanup */
1380 + for (i = 0; i < ctx->window; i++)
1381 + {
1382 + bi_depermanent(ctx->g[i]);
1383 + bi_free(ctx, ctx->g[i]);
1384 + }
1385 +
1386 + free(ctx->g);
1387 + bi_free(ctx, bi);
1388 + bi_free(ctx, biexp);
1389 + return biR;
1390 +}
1391 +
1392 +/** @} */
1393 --- /dev/null
1394 +++ b/net/rsa/bigint.h
1395 @@ -0,0 +1,73 @@
1396 +/*
1397 + * Copyright(C) 2006
1398 + *
1399 + * This library is free software; you can redistribute it and/or modify
1400 + * it under the terms of the GNU Lesser General Public License as published by
1401 + * the Free Software Foundation; either version 2 of the License, or
1402 + * (at your option) any later version.
1403 + *
1404 + * This library is distributed in the hope that it will be useful,
1405 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1406 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1407 + * GNU Lesser General Public License for more details.
1408 + *
1409 + * You should have received a copy of the GNU Lesser General Public License
1410 + * along with this library; if not, write to the Free Software
1411 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1412 + *
1413 + * Trimmed down from axTLS
1414 + *
1415 + * $Id: bigint.h 392 2007-06-25 16:24:51Z pablo.martin $
1416 + *
1417 + */
1418 +
1419 +#ifndef BIGINT_HEADER
1420 +#define BIGINT_HEADER
1421 +
1422 +#define CONFIG_BIGINT_CLASSICAL 1
1423 +
1424 +#define SOCKET_READ(A,B,C) read(A,B,C)
1425 +#define SOCKET_WRITE(A,B,C) write(A,B,C)
1426 +#define SOCKET_CLOSE(A) close(A)
1427 +#define TTY_FLUSH()
1428 +
1429 +#include "bigint_impl.h"
1430 +
1431 +#ifndef CONFIG_BIGINT_CHECK_ON
1432 +#define check(A) /**< disappears in normal production mode */
1433 +#endif
1434 +BI_CTX *bi_initialize(void);
1435 +void bi_terminate(BI_CTX *ctx);
1436 +void bi_permanent(bigint *bi);
1437 +void bi_depermanent(bigint *bi);
1438 +void bi_free(BI_CTX *ctx, bigint *bi);
1439 +bigint *bi_copy(bigint *bi);
1440 +bigint *bi_clone(BI_CTX *ctx, const bigint *bi);
1441 +void bi_export(BI_CTX *ctx, bigint *bi, uint8_t *data, int size);
1442 +bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int len);
1443 +bigint *int_to_bi(BI_CTX *ctx, comp i);
1444 +
1445 +/* the functions that actually do something interesting */
1446 +bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib);
1447 +bigint *bi_subtract(BI_CTX *ctx, bigint *bia,
1448 + bigint *bib, int *is_negative);
1449 +bigint *bi_divide(BI_CTX *ctx, bigint *bia, bigint *bim, int is_mod);
1450 +bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib);
1451 +bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp);
1452 +bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp);
1453 +int bi_compare(bigint *bia, bigint *bib);
1454 +void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset);
1455 +void bi_free_mod(BI_CTX *ctx, int mod_offset);
1456 +
1457 +/**
1458 + * @def bi_mod
1459 + * Find the residue of B. bi_set_mod() must be called before hand.
1460 + */
1461 +#define bi_mod(A, B) bi_divide(A, B, ctx->bi_mod[ctx->mod_offset], 1)
1462 +
1463 +#define bi_residue(A, B) bi_mod(A, B)
1464 +
1465 +#define bi_square(A, B) bi_multiply(A, bi_copy(B), B)
1466 +
1467 +#endif
1468 +
1469 --- /dev/null
1470 +++ b/net/rsa/bigint_impl.h
1471 @@ -0,0 +1,109 @@
1472 +/*
1473 + * Copyright(C) 2006
1474 + *
1475 + * This library is free software; you can redistribute it and/or modify
1476 + * it under the terms of the GNU Lesser General Public License as published by
1477 + * the Free Software Foundation; either version 2.1 of the License, or
1478 + * (at your option) any later version.
1479 + *
1480 + * This library is distributed in the hope that it will be useful,
1481 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1482 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1483 + * GNU Lesser General Public License for more details.
1484 + *
1485 + * You should have received a copy of the GNU Lesser General Public License
1486 + * along with this library; if not, write to the Free Software
1487 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1488 + */
1489 +
1490 +#ifndef BIGINT_IMPL_HEADER
1491 +#define BIGINT_IMPL_HEADER
1492 +
1493 +#include <linux/types.h>
1494 +#include <common.h>
1495 +
1496 +/* Maintain a number of precomputed variables when doing reduction */
1497 +#define BIGINT_M_OFFSET 0 /**< Normal modulo offset. */
1498 +#ifdef CONFIG_BIGINT_CRT
1499 +#define BIGINT_P_OFFSET 1 /**< p modulo offset. */
1500 +#define BIGINT_Q_OFFSET 2 /**< q module offset. */
1501 +#define BIGINT_NUM_MODS 3 /**< The number of modulus constants used. */
1502 +#else
1503 +#define BIGINT_NUM_MODS 1
1504 +#endif
1505 +
1506 +/* Architecture specific functions for big ints */
1507 +// #ifdef WIN32
1508 +// #define COMP_RADIX 4294967296i64
1509 +// #define COMP_BIG_MSB 0x8000000000000000i64
1510 +// #else
1511 +#define COMP_RADIX 4294967296ULL /**< Max component + 1 */
1512 +#define COMP_BIG_MSB 0x8000000000000000ULL /**< (Max dbl comp + 1)/ 2 */
1513 +//#endif
1514 +#define COMP_BIT_SIZE 32 /**< Number of bits in a component. */
1515 +#define COMP_BYTE_SIZE 4 /**< Number of bytes in a component. */
1516 +#define COMP_NUM_NIBBLES 8 /**< Used For diagnostics only. */
1517 +
1518 +typedef uint32_t comp; /**< A single precision component. */
1519 +typedef uint64_t long_comp; /**< A double precision component. */
1520 +typedef int64_t slong_comp; /**< A signed double precision component. */
1521 +
1522 +/**
1523 + * @struct _bigint
1524 + * @brief A big integer basic object
1525 + */
1526 +struct _bigint
1527 +{
1528 + struct _bigint* next; /**< The next bigint in the cache. */
1529 + short size; /**< The number of components in this bigint. */
1530 + short max_comps; /**< The heapsize allocated for this bigint */
1531 + int refs; /**< An internal reference count. */
1532 + comp* comps; /**< A ptr to the actual component data */
1533 +};
1534 +
1535 +typedef struct _bigint bigint; /**< An alias for _bigint */
1536 +
1537 +/**
1538 + * Maintains the state of the cache, and a number of variables used in
1539 + * reduction.
1540 + */
1541 +typedef struct /**< A big integer "session" context. */
1542 +{
1543 + bigint *active_list; /**< Bigints currently used. */
1544 + bigint *free_list; /**< Bigints not used. */
1545 + bigint *bi_radix; /**< The radix used. */
1546 + bigint *bi_mod[BIGINT_NUM_MODS]; /**< modulus */
1547 +
1548 +#if defined(CONFIG_BIGINT_MONTGOMERY)
1549 + bigint *bi_RR_mod_m[BIGINT_NUM_MODS]; /**< R^2 mod m */
1550 + bigint *bi_R_mod_m[BIGINT_NUM_MODS]; /**< R mod m */
1551 + comp N0_dash[BIGINT_NUM_MODS];
1552 +#elif defined(CONFIG_BIGINT_BARRETT)
1553 + bigint *bi_mu[BIGINT_NUM_MODS]; /**< Storage for mu */
1554 +#endif
1555 + bigint *bi_normalised_mod[BIGINT_NUM_MODS]; /**< Normalised mod storage. */
1556 + bigint **g; /**< Used by sliding-window. */
1557 + int window; /**< The size of the sliding window */
1558 +
1559 + int active_count; /**< Number of active bigints. */
1560 + int free_count; /**< Number of free bigints. */
1561 +
1562 +#ifdef CONFIG_BIGINT_MONTGOMERY
1563 + uint8_t use_classical; /**< Use classical reduction. */
1564 +#endif
1565 + uint8_t mod_offset; /**< The mod offset we are using */
1566 +} BI_CTX;
1567 +
1568 +#if 0
1569 +#define max(a,b) ((a)>(b)?(a):(b)) /**< Find the maximum of 2 numbers. */
1570 +#define min(a,b) ((a)<(b)?(a):(b)) /**< Find the minimum of 2 numbers. */
1571 +#endif
1572 +
1573 +#define PERMANENT 0x7FFF55AA /**< A magic number for permanents. */
1574 +
1575 +#define V1 v->comps[v->size-1] /**< v1 for division */
1576 +#define V2 v->comps[v->size-2] /**< v2 for division */
1577 +#define U(j) tmp_u->comps[tmp_u->size-j-1] /**< uj for division */
1578 +#define Q(j) quotient->comps[quotient->size-j-1] /**< qj for division */
1579 +
1580 +#endif
1581 --- /dev/null
1582 +++ b/net/rsa/div64.h
1583 @@ -0,0 +1,113 @@
1584 +/*
1585 + * Copyright (C) 2000, 2004 Maciej W. Rozycki
1586 + * Copyright (C) 2003 Ralf Baechle
1587 + *
1588 + * This file is subject to the terms and conditions of the GNU General Public
1589 + * License. See the file "COPYING" in the main directory of this archive
1590 + * for more details.
1591 + */
1592 +#ifndef _ASM_DIV64_H
1593 +#define _ASM_DIV64_H
1594 +
1595 +#if (_MIPS_SZLONG == 32)
1596 +
1597 +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
1598 +#define GCC_REG_ACCUM "$0"
1599 +#else
1600 +#define GCC_REG_ACCUM "accum"
1601 +#endif
1602 +
1603 +
1604 +//#include <asm/compiler.h>
1605 +
1606 +/*
1607 + * No traps on overflows for any of these...
1608 + */
1609 +
1610 +#define do_div64_32(res, high, low, base) ({ \
1611 + unsigned long __quot, __mod; \
1612 + unsigned long __cf, __tmp, __tmp2, __i; \
1613 + \
1614 + __asm__(".set push\n\t" \
1615 + ".set noat\n\t" \
1616 + ".set noreorder\n\t" \
1617 + "move %2, $0\n\t" \
1618 + "move %3, $0\n\t" \
1619 + "b 1f\n\t" \
1620 + " li %4, 0x21\n" \
1621 + "0:\n\t" \
1622 + "sll $1, %0, 0x1\n\t" \
1623 + "srl %3, %0, 0x1f\n\t" \
1624 + "or %0, $1, %5\n\t" \
1625 + "sll %1, %1, 0x1\n\t" \
1626 + "sll %2, %2, 0x1\n" \
1627 + "1:\n\t" \
1628 + "bnez %3, 2f\n\t" \
1629 + " sltu %5, %0, %z6\n\t" \
1630 + "bnez %5, 3f\n" \
1631 + "2:\n\t" \
1632 + " addiu %4, %4, -1\n\t" \
1633 + "subu %0, %0, %z6\n\t" \
1634 + "addiu %2, %2, 1\n" \
1635 + "3:\n\t" \
1636 + "bnez %4, 0b\n\t" \
1637 + " srl %5, %1, 0x1f\n\t" \
1638 + ".set pop" \
1639 + : "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \
1640 + "=&r" (__i), "=&r" (__tmp2) \
1641 + : "Jr" (base), "0" (high), "1" (low)); \
1642 + \
1643 + (res) = __quot; \
1644 + __mod; })
1645 +
1646 +#define do_div(n, base) ({ \
1647 + unsigned long long __quot; \
1648 + unsigned long __mod; \
1649 + unsigned long long __div; \
1650 + unsigned long __upper, __low, __high, __base; \
1651 + \
1652 + __div = (n); \
1653 + __base = (base); \
1654 + \
1655 + __high = __div >> 32; \
1656 + __low = __div; \
1657 + __upper = __high; \
1658 + \
1659 + if (__high) \
1660 + __asm__("divu $0, %z2, %z3" \
1661 + : "=h" (__upper), "=l" (__high) \
1662 + : "Jr" (__high), "Jr" (__base) \
1663 + : GCC_REG_ACCUM); \
1664 + \
1665 + __mod = do_div64_32(__low, __upper, __low, __base); \
1666 + \
1667 + __quot = __high; \
1668 + __quot = __quot << 32 | __low; \
1669 + (n) = __quot; \
1670 + __mod; })
1671 +#endif /* (_MIPS_SZLONG == 32) */
1672 +
1673 +#if (_MIPS_SZLONG == 64)
1674 +
1675 +/*
1676 + * Hey, we're already 64-bit, no
1677 + * need to play games..
1678 + */
1679 +#define do_div(n, base) ({ \
1680 + unsigned long __quot; \
1681 + unsigned int __mod; \
1682 + unsigned long __div; \
1683 + unsigned int __base; \
1684 + \
1685 + __div = (n); \
1686 + __base = (base); \
1687 + \
1688 + __mod = __div % __base; \
1689 + __quot = __div / __base; \
1690 + \
1691 + (n) = __quot; \
1692 + __mod; })
1693 +
1694 +#endif /* (_MIPS_SZLONG == 64) */
1695 +
1696 +#endif /* _ASM_DIV64_H */
1697 --- /dev/null
1698 +++ b/net/rsa/dump_key.c
1699 @@ -0,0 +1,29 @@
1700 +#include <stdio.h>
1701 +#include <stdlib.h>
1702 +#include <sys/types.h>
1703 +#include <sys/stat.h>
1704 +#include <unistd.h>
1705 +
1706 +int main(int argc, char **argv)
1707 +{
1708 + FILE *fp = fopen("public_fon_rsa_key_6.pem", "r");
1709 + struct stat s;
1710 + unsigned char *b;
1711 + int i;
1712 + if(!fp)
1713 + return 1;
1714 + stat("public_fon_rsa_key_6.pem", &s);
1715 + b = malloc(s.st_size);
1716 + fread(b, s.st_size, 1, fp);
1717 + fclose(fp);
1718 + printf("unsigned char public_key[] = {\n\t");
1719 + for(i = 0;i < s.st_size; i++)
1720 + {
1721 + printf("0x%02X,", b[i]);
1722 + if(i%16 == 15)
1723 + printf("\n\t");
1724 + }
1725 + printf("};\n");
1726 +// printf("\n%d %d\n", i, s.st_size);
1727 + return 0;
1728 +}
1729 --- /dev/null
1730 +++ b/net/rsa/foncheckrsa.c
1731 @@ -0,0 +1,79 @@
1732 +/*
1733 + * RSA + RIPEMD160 signature verification command
1734 + *
1735 + * Copyright (C) 2007 FON Wireless Ltd.
1736 + *
1737 + * This program is free software; you can redistribute it and/or
1738 + * modify it under the terms of the GNU General Public License
1739 + * as published by the Free Software Foundation; either version 2
1740 + * of the License, or (at your option) any later version.
1741 + *
1742 + * This program is distributed in the hope that it will be useful,
1743 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1744 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1745 + * GNU General Public License for more details.
1746 + *
1747 + * You should have received a copy of the GNU General Public License
1748 + * along with this program; if not, write to the Free Software
1749 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1750 + *
1751 + * Created: 20060728 Pablo Martín Medrano <pablo@fon.com>
1752 + *
1753 + * $Id: foncheckrsa.c 332 2007-05-02 09:45:54Z pablo.martin $
1754 + */
1755 +#include <stdio.h>
1756 +#include <stdlib.h>
1757 +#include <sys/types.h>
1758 +#include <sys/stat.h>
1759 +#include <fcntl.h>
1760 +#include <string.h>
1761 +#include <errno.h>
1762 +#include <unistd.h>
1763 +#include "fonrsa.h"
1764 +
1765 +int main(int argc, char **argv)
1766 +{
1767 + int fd, i;
1768 + FONRSA_ERROR fonrsa_error;
1769 + void *handle;
1770 +
1771 + if (argc != 4) {
1772 + fprintf(stderr, " Usage: foncheckrsa [public_key.der] [signature] [file]\n");
1773 + fprintf(stderr, " Pablo Martín Medrano <pablo@fon.com>\n");
1774 + fprintf(stderr, " RIPEMD-160 software written by Antoon Bosselaers,\n");
1775 + fprintf(stderr, " available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.\n");
1776 + fprintf(stderr, " Uses the axTLS library bigint implementation (libfonrsa)\n");
1777 + fprintf(stderr, " http://www.leroc.com.au/axTLS/\n");
1778 + return -1;
1779 + }
1780 + /* Check the existence of input files */
1781 + for (i = 1; i < 4; i++) {
1782 + if ((fd = open(argv[i], O_RDONLY)) == -1) {
1783 + fprintf(stderr, "Error: opening \"%s\": %s\n", argv[i],
1784 + strerror(errno));
1785 + fprintf(stderr, "Bailing out...");
1786 + exit(-2);
1787 + }
1788 + close(fd);
1789 + }
1790 + handle = FR_init(argv[1]);
1791 + if (handle == NULL) {
1792 + printf("Error loading keys in %s\n", argv[1]);
1793 + return 1;
1794 + }
1795 + fonrsa_error = FR_verify_file(handle, argv[3], argv[2]);
1796 + FR_end(handle);
1797 + switch (fonrsa_error) {
1798 + case FONRSA_OK:
1799 + printf("Verified OK\n");
1800 + return 0;
1801 + case FONRSA_VERIFICATION_FAILURE:
1802 + printf("Verification failure\n");
1803 + return 1;
1804 + default:
1805 + printf("Verification error\n");
1806 + return -1;
1807 + }
1808 + return -1;
1809 +}
1810 +
1811 --- /dev/null
1812 +++ b/net/rsa/fonrsa.c
1813 @@ -0,0 +1,584 @@
1814 +/*
1815 + * FONSM RSA handling library
1816 + *
1817 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
1818 + *
1819 + * This library is free software; you can redistribute it and/or modify
1820 + * it under the terms of the GNU Lesser General Public License as published by
1821 + * the Free Software Foundation; either version 2 of the License, or
1822 + * (at your option) any later version.
1823 + *
1824 + * This library is distributed in the hope that it will be useful,
1825 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1826 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1827 + * GNU Lesser General Public License for more details.
1828 + *
1829 + * You should have received a copy of the GNU Lesser General Public License
1830 + * along with this library; if not, write to the Free Software
1831 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1832 + *
1833 + * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
1834 + *
1835 + * Based on axTLS
1836 + *
1837 + * $Id: fonrsa.c 405 2007-09-19 15:26:17Z jesus.pico $
1838 + */
1839 +#include <sys/types.h>
1840 +#include <stdlib.h>
1841 +#include <stdio.h>
1842 +#include <string.h>
1843 +#include <sys/types.h>
1844 +#include <sys/stat.h>
1845 +#include <fcntl.h>
1846 +#include <unistd.h>
1847 +#include <errno.h>
1848 +#include "rmd160.h"
1849 +#include "bigint.h"
1850 +#include "fonrsa.h"
1851 +#include "base64.h"
1852 +
1853 +typedef struct {
1854 + uint8_t *buffer;
1855 + size_t size;
1856 +} DER_key;
1857 +
1858 +typedef struct {
1859 + bigint *m; /* modulus */
1860 + bigint *e; /* public exponent */
1861 + int num_octets;
1862 + BI_CTX *bi_ctx; /* big integer handle */
1863 +} RSA_parameters;
1864 +
1865 +typedef struct {
1866 + DER_key *derkey;
1867 + RSA_parameters *rsaparms;
1868 +} RSA;
1869 +
1870 +static uint8_t *CH_load_raw_file(char *filename, size_t *size);
1871 +static DER_key *CH_load_der_key(char *filename);
1872 +static void CH_free_der_key(DER_key *key);
1873 +static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters);
1874 +void CH_pub_key_new(RSA_parameters **rsa_parameters, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len);
1875 +int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out);
1876 +byte *RMDbinary(char *fname);
1877 +int CH_get_rmd160_hash_from_signature(byte *hash, char *signature_file, char *public_key_file);
1878 +static unsigned char *load_file_in_buffer(char *path, int *size);
1879 +static int save_file_from_buffer(char *path, unsigned char *buffer, int size);
1880 +int ExtractPadding(uint8_t* OutputBuffer, uint8_t* InputBuffer, int LengthOfInputBuffer);
1881 +
1882 +#define RMDsize 160 /* A RIPEMD-160 hash has 160 bits */
1883 +
1884 +/*
1885 + * returns RMD(message in file fname) fname is read as binary data.
1886 + * non-reentrant
1887 + */
1888 +byte *RMDbinary(char *fname)
1889 +{
1890 + FILE *mf; /* pointer to file <fname> */
1891 + byte data[1024]; /* contains current mess. block */
1892 + dword nbytes; /* length of this block */
1893 + dword MDbuf[RMDsize / 32]; /* contains (A, B, C, D(, E)) */
1894 + static byte hashcode[RMDsize / 8]; /* for final hash-value */
1895 + dword X[16]; /* current 16-word chunk */
1896 + unsigned int i, j; /* counters */
1897 + dword length[2]; /* length in bytes of message */
1898 + dword offset; /* # of unprocessed bytes at */
1899 + /* call of MDfinish */
1900 +
1901 + /* initialize */
1902 + if ((mf = fopen(fname, "rb")) == NULL) {
1903 + fprintf(stderr, "\nRMDbinary: cannot open file \"%s\".\n",
1904 + fname);
1905 + exit(1);
1906 + }
1907 + MDinit(MDbuf);
1908 + length[0] = 0;
1909 + length[1] = 0;
1910 + while ((nbytes = fread(data, 1, 1024, mf)) != 0) {
1911 + /* process all complete blocks */
1912 + for (i = 0; i < (nbytes >> 6); i++) {
1913 + for (j = 0; j < 16; j++)
1914 + X[j] = BYTES_TO_DWORD(data + 64 * i + 4 * j);
1915 + compress(MDbuf, X);
1916 + }
1917 + /* update length[] */
1918 + if (length[0] + nbytes < length[0])
1919 + length[1]++; /* overflow to msb of length */
1920 + length[0] += nbytes;
1921 + }
1922 + /* finish: */
1923 + offset = length[0] & 0x3C0; /* extract bytes 6 to 10 inclusive */
1924 + MDfinish(MDbuf, data + offset, length[0], length[1]);
1925 +
1926 + for (i = 0; i < RMDsize / 8; i += 4) {
1927 + hashcode[i] = MDbuf[i >> 2];
1928 + hashcode[i + 1] = (MDbuf[i >> 2] >> 8);
1929 + hashcode[i + 2] = (MDbuf[i >> 2] >> 16);
1930 + hashcode[i + 3] = (MDbuf[i >> 2] >> 24);
1931 + }
1932 + fclose(mf);
1933 +
1934 + return (byte *) hashcode;
1935 +}
1936 +byte *RMDbinary_buffer(char *buffer, int size_buffer)
1937 +{
1938 + return NULL;
1939 +}
1940 +
1941 +/*
1942 + * Extracts the RMD 160 hash from the signature file
1943 + */
1944 +int CH_get_rmd160_hash_from_signature(byte *hash, char *signature_file, char *public_key_file)
1945 +{
1946 + RSA_parameters *rsa_parameters;
1947 + DER_key *derkey;
1948 + uint8_t *signature;
1949 + size_t signature_size;
1950 + uint8_t *decrypted;
1951 +
1952 + signature = CH_load_raw_file(signature_file, &signature_size);
1953 + if ((signature == NULL)||(signature_size != 512)) {
1954 + fprintf(stderr, "Error: Loading signature key '%s'\n", signature_file);
1955 + exit(-1);
1956 + }
1957 + derkey = CH_load_der_key(public_key_file);
1958 + if (derkey == NULL) {
1959 + fprintf(stderr, "Error: opening DER key file '%s'\n", public_key_file);
1960 + exit(-1);
1961 + }
1962 + if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
1963 + fprintf(stderr, "Error: Extracting public key from DER file\n");
1964 + exit(-1);
1965 + }
1966 + CH_free_der_key(derkey);
1967 + if (rsa_parameters->num_octets != 512)
1968 + fprintf(stderr, "Error: The RSA public key size is not 4096 bits %d\n", rsa_parameters->num_octets);
1969 + decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
1970 + if (CH_decrypt(rsa_parameters, signature, decrypted)) {
1971 + fprintf(stderr, "Error: Decrypting signature\n");
1972 + exit(-1);
1973 + }
1974 + memcpy(hash, decrypted + 492, 20);
1975 + free(decrypted);
1976 + free(signature);
1977 + return 0;
1978 +}
1979 +
1980 +/*
1981 + * Decrypts the signature buffer using the rsa public key loaded
1982 + */
1983 +int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out)
1984 +{
1985 + bigint *dat_bi;
1986 + bigint *decrypted_bi;
1987 + int byte_size;
1988 +
1989 + byte_size = rsa->num_octets;
1990 + dat_bi = bi_import(rsa->bi_ctx, buffer_in, byte_size);
1991 + rsa->bi_ctx->mod_offset = BIGINT_M_OFFSET;
1992 + bi_copy(rsa->m);
1993 + decrypted_bi = bi_mod_power(rsa->bi_ctx, dat_bi, rsa->e);
1994 + bi_export(rsa->bi_ctx, decrypted_bi, buffer_out, byte_size);
1995 + return 0;
1996 +}
1997 +/*
1998 + * Loads a file in a uint8_t buffer
1999 + */
2000 +static uint8_t *CH_load_raw_file(char *filename, size_t *size)
2001 +{
2002 + struct stat st;
2003 + int fd;
2004 + ssize_t br;
2005 + uint8_t *ret;
2006 +
2007 + if ((stat(filename, &st)) == -1)
2008 + return NULL;
2009 + if ((ret = (uint8_t *)malloc(st.st_size)) == NULL)
2010 + return NULL;
2011 + fd = open(filename, O_RDONLY);
2012 + if (fd == -1) {
2013 + free(ret);
2014 + return NULL;
2015 + }
2016 + br = read(fd, ret, st.st_size);
2017 + close(fd);
2018 + if (br != st.st_size) {
2019 + free(ret);
2020 + return NULL;
2021 + }
2022 + *size = st.st_size;
2023 + return ret;
2024 +}
2025 +/*
2026 + * Loads a .der file in a buffer
2027 + */
2028 +static DER_key *CH_load_der_key(char *filename)
2029 +{
2030 + DER_key *ret;
2031 +
2032 + if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
2033 + return NULL;
2034 + if ((ret->buffer = CH_load_raw_file(filename, &(ret->size))) == NULL) {
2035 + free(ret);
2036 + return NULL;
2037 + }
2038 + return ret;
2039 +}
2040 +/*
2041 + * CH_load_pem_key
2042 + */
2043 +static DER_key *CH_load_pem_key(char *filename)
2044 +{
2045 + DER_key *ret;
2046 + uint8_t *buffer;
2047 + char *b64,*p,*t;
2048 + char key[1024];
2049 + size_t filesize;
2050 + int size;
2051 +
2052 + if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
2053 + return NULL;
2054 + if ((buffer = CH_load_raw_file(filename, &filesize)) == NULL) {
2055 + free(ret);
2056 + return NULL;
2057 + }
2058 + p = (char *)buffer;
2059 + while ((*p != '\n') && (*p != '\0'))
2060 + p++;
2061 + if (*p == '\0') {
2062 + free(ret);
2063 + return NULL;
2064 + }
2065 + p++;
2066 + b64 = t = p;
2067 + while((p - b64) <= filesize) {
2068 + if ((*p == '-')) {
2069 + break;
2070 + } else if ((*p != '\n') && (*p != ' ') && (*p != '\t')) {
2071 + *t = *p;
2072 + t++;
2073 + }
2074 + p++;
2075 + }
2076 + *t = '\0';
2077 + size = B64_decode(b64, key, strlen(b64), 1024);
2078 + if (size < 0) {
2079 + free(buffer);
2080 + free(ret);
2081 + return NULL;
2082 + }
2083 + free(buffer);
2084 + ret->buffer = (char *)malloc(size);
2085 + ret->size = size;
2086 + memcpy((void *)ret->buffer, (void *)key, size);
2087 + return ret;
2088 +}
2089 +
2090 +/*
2091 + * CH_free_der_key
2092 + */
2093 +static void CH_free_der_key(DER_key *key)
2094 +{
2095 + free(key->buffer);
2096 + free(key);
2097 +}
2098 +
2099 +/*
2100 + * Get the public key specifics from an ASN.1 encoded file
2101 + * A function lacking in the exported axTLS API
2102 + *
2103 + * This is a really weird hack that only works with RSA public key
2104 + * files
2105 + */
2106 +static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters)
2107 +{
2108 + uint8_t *modulus, *pub_exp;
2109 + int mod_len, pub_len;
2110 +
2111 + pub_len = 3;
2112 + mod_len = len - 37;
2113 + if (buf[0] != 0x30) {
2114 + return -1;
2115 + }
2116 +
2117 + pub_exp = (uint8_t *)malloc(3);
2118 + modulus = (uint8_t *)malloc(mod_len);
2119 + memcpy(modulus, buf + 32 , mod_len);
2120 + memcpy(pub_exp, buf + 34 + mod_len, 3);
2121 + if (mod_len <= 0 || pub_len <= 0 )
2122 + return -1;
2123 + CH_pub_key_new(rsa_parameters, modulus, mod_len, pub_exp, pub_len);
2124 +
2125 + free(modulus);
2126 + free(pub_exp);
2127 + return 0;
2128 +}
2129 +
2130 +/*
2131 + * Similar to RSA_pub_key_new, rewritten to make this program depend only on bi module
2132 + */
2133 +void CH_pub_key_new(RSA_parameters **rsa, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len)
2134 +{
2135 + RSA_parameters *rsa_parameters;
2136 +
2137 + BI_CTX *bi_ctx = bi_initialize();
2138 + *rsa = (RSA_parameters *)calloc(1, sizeof(RSA_parameters));
2139 + rsa_parameters = *rsa;
2140 + rsa_parameters->bi_ctx = bi_ctx;
2141 + rsa_parameters->num_octets = (mod_len & 0xFFF0);
2142 + rsa_parameters->m = bi_import(bi_ctx, modulus, mod_len);
2143 + bi_set_mod(bi_ctx, rsa_parameters->m, BIGINT_M_OFFSET);
2144 + rsa_parameters->e = bi_import(bi_ctx, pub_exp, pub_len);
2145 + bi_permanent(rsa_parameters->e);
2146 +}
2147 +
2148 +static unsigned char *load_file_in_buffer(char *path, int *size)
2149 +{
2150 + unsigned char *buffer;
2151 + struct stat st;
2152 + int fd;
2153 +
2154 + if (stat(path, &st))
2155 + return NULL;
2156 + buffer = (unsigned char *)malloc(st.st_size);
2157 + if (buffer == NULL)
2158 + return NULL;
2159 + if ((fd = open(path, O_RDONLY)) == -1) {
2160 + free(buffer);
2161 + return NULL;
2162 + }
2163 + if (read(fd, (void *)buffer,st.st_size) != (ssize_t)st.st_size) {
2164 + free(buffer);
2165 + close(fd);
2166 + return NULL;
2167 + }
2168 + *size = (int)st.st_size;
2169 + close(fd);
2170 + return buffer;
2171 +}
2172 +
2173 +static int save_file_from_buffer(char *path, unsigned char *buffer, int size)
2174 +{
2175 + int fd;
2176 +
2177 + if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) == -1)
2178 + return -1;
2179 + if (write(fd, buffer, (size_t)size) != ((ssize_t)size)) {
2180 + close(fd);
2181 + return -1;
2182 + }
2183 + close(fd);
2184 + return 0;
2185 +}
2186 +
2187 +/* FR_init */
2188 +void *FR_init(char *public_key_path)
2189 +{
2190 + DER_key *derkey;
2191 + RSA_parameters *rsa_parameters;
2192 + char *ending;
2193 +
2194 + ending = public_key_path + strlen(public_key_path) - 3;
2195 + if (!strcmp(ending, "der"))
2196 + derkey = CH_load_der_key(public_key_path);
2197 + else if (!strcmp(ending, "pem"))
2198 + derkey = CH_load_pem_key(public_key_path);
2199 + else {
2200 + fprintf(stderr, "Error: unknown key format\n");
2201 + exit(-1);
2202 + }
2203 + if (derkey == NULL) {
2204 + fprintf(stderr, "Error: opening key file '%s'\n", public_key_path);
2205 + exit(-1);
2206 + }
2207 + if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
2208 + fprintf(stderr, "Error: Extracting public key from file\n");
2209 + exit(-1);
2210 + }
2211 + CH_free_der_key(derkey);
2212 + return (void *)rsa_parameters;
2213 +}
2214 +
2215 +/* FR_end */
2216 +FONRSA_ERROR FR_end(void *handle)
2217 +{
2218 + RSA_parameters *rsa_parameters = (RSA_parameters *)handle;
2219 +
2220 + free(rsa_parameters);
2221 + return FONRSA_OK;
2222 +}
2223 +
2224 +/* FR_decrypt_buffer */
2225 +FONRSA_ERROR FR_decrypt_buffer(void *handler, unsigned char *cryptext, int cryptext_size,
2226 + unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size)
2227 +{
2228 + RSA_parameters *rsaparms = (RSA_parameters *)handler;
2229 +
2230 + if (cryptext_size != rsaparms->num_octets) {
2231 + return FONRSA_SIZE;
2232 + }
2233 + if (plaintext_buffer_size < cryptext_size) {
2234 + return FONRSA_SIZE;
2235 + }
2236 + if (CH_decrypt(rsaparms, (uint8_t *)cryptext, (uint8_t *)plaintext)) {
2237 + return FONRSA_DECRYPT;
2238 + }
2239 + *plaintext_size = cryptext_size;
2240 + return FONRSA_OK;
2241 +}
2242 +
2243 +FONRSA_ERROR FR_decrypt_buffer_v2(void *handler, unsigned char *cryptext, int cryptext_size,
2244 + unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size)
2245 +{
2246 + unsigned char* AuxBuffer;
2247 + int AuxSize;
2248 +
2249 + AuxBuffer = (unsigned char*)malloc(cryptext_size);
2250 +
2251 + RSA_parameters *rsaparms = (RSA_parameters *)handler;
2252 +
2253 + if (cryptext_size != rsaparms->num_octets) {
2254 + return FONRSA_SIZE;
2255 + }
2256 + if (plaintext_buffer_size < cryptext_size) {
2257 + return FONRSA_SIZE;
2258 + }
2259 + if (CH_decrypt(rsaparms, (uint8_t *)cryptext, (uint8_t *)AuxBuffer)) {
2260 + return FONRSA_DECRYPT;
2261 + }
2262 + if ((AuxSize = ExtractPadding((uint8_t*)plaintext, (uint8_t*)AuxBuffer, cryptext_size)) < 0)
2263 + {
2264 + printf("Incorrect Padding decrypting buffer");
2265 + return FONRSA_DECRYPT;
2266 + }
2267 + *plaintext_size = AuxSize;
2268 + return FONRSA_OK;
2269 +}
2270 +
2271 +/*
2272 + *
2273 + * Implementation of PKCS 1.5 padding, borrowed from
2274 + * Tom's code (public domain)
2275 + */
2276 +
2277 +/* Standalone FR_verify_file */
2278 +FONRSA_ERROR FR_verify_file(void *handler, char *file_path, char *signature_file_path)
2279 +{
2280 + int j;
2281 + byte *hashcode;
2282 + byte hash[20];
2283 + uint8_t *decrypted;
2284 + RSA_parameters *rsa_parameters = (RSA_parameters *)handler;
2285 + char *signature_buffer;
2286 + int signature_size;
2287 +
2288 + /* Calculates the RIPEMD-160 hash of the file */
2289 + hashcode = RMDbinary (file_path);
2290 + /* Decrypts the signature file using the RSA public key */
2291 + signature_buffer = load_file_in_buffer(signature_file_path, &signature_size);
2292 + if (signature_buffer == NULL)
2293 + return FONRSA_OPENKEY;
2294 +
2295 + if (rsa_parameters->num_octets != signature_size)
2296 + return FONRSA_SIZE;
2297 + decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
2298 + if (CH_decrypt(rsa_parameters, signature_buffer, decrypted)) {
2299 + fprintf(stderr, "Error: Decrypting signature\n");
2300 + exit(-1);
2301 + }
2302 + memcpy(hash, decrypted + 492, 20);
2303 + free(decrypted);
2304 + free(signature_buffer);
2305 + for (j = 0; j < RMDsize/8; j++) {
2306 + if (hash[j] != hashcode[j])
2307 + return FONRSA_VERIFICATION_FAILURE;
2308 + }
2309 + return FONRSA_OK;
2310 +}
2311 +
2312 +/* FR_decrypt_file */
2313 +FONRSA_ERROR FR_decrypt_file(void *handle, char *crypted_file_path, char *plaintext_file_path)
2314 +{
2315 + int size;
2316 + FONRSA_ERROR ret;
2317 + char *filebuffer;
2318 + char crypted[1024];
2319 + int crypted_size;
2320 +
2321 + if ((filebuffer = load_file_in_buffer(crypted_file_path, &size)) == NULL) {
2322 + return FONRSA_LOADFILE;
2323 + }
2324 +
2325 + ret = FR_decrypt_buffer(handle, filebuffer, size, crypted, 1024, &crypted_size);
2326 + if (ret != FONRSA_OK) {
2327 + free(filebuffer);
2328 + return ret;
2329 + }
2330 + free(filebuffer);
2331 +
2332 + if (save_file_from_buffer(plaintext_file_path, crypted, crypted_size)) {
2333 + printf("Error writing %lu bytes into %s", crypted_size, plaintext_file_path);
2334 + return FONRSA_SAVEFILE;
2335 + }
2336 + return FONRSA_OK;
2337 +}
2338 +
2339 +int ExtractPadding(uint8_t* OutputBuffer, uint8_t* InputBuffer, int LengthOfInputBuffer)
2340 +{
2341 + int i;
2342 +
2343 + //First typical checks...
2344 + if (LengthOfInputBuffer < MINIMUM_PADING_BYTES_PKCS_1_5)
2345 + {
2346 + fprintf(stderr, "Error:ExtractPadding: Error, Length of input buffer is too short.\n");
2347 + return -1;
2348 + }
2349 + else if((InputBuffer[0] != 0) || (InputBuffer[1] > 2)) //Necessary header of Padding...
2350 + {
2351 + fprintf(stderr, "Error:ExtractPadding: Error, Padding header is incorrect.\n");
2352 + return -1;
2353 + }
2354 + for (i=2; i < LengthOfInputBuffer; i++) //Variable size of non-zero padding....
2355 + {
2356 + if (InputBuffer[i] == 0) break; //This is the end of Padding.
2357 + }
2358 + //We need to evaluate if there is an existing message...
2359 + if (i < LengthOfInputBuffer - 2)
2360 + {//Ok, Padding is extracted... copying the message and finishing...
2361 + memcpy(OutputBuffer, &(InputBuffer[i + 1]), LengthOfInputBuffer - (i + 1));
2362 + return LengthOfInputBuffer - (i + 1);
2363 + }
2364 + //If we have reached to this point, then an error has occurred...
2365 + return -1;
2366 +}
2367 +
2368 +#ifdef __MAINTEST__
2369 +int main(int argc, char **argv)
2370 +{
2371 + void *handle = NULL;
2372 + FONRSA_ERROR ret;
2373 + char *filebuffer = NULL;
2374 + char crypted[1024];
2375 + int size, crypted_size;
2376 +
2377 + if (argc != 4) {
2378 + printf("Usage: %s <key_file> <crypted_file> <output_file>\n", argv[0]);
2379 + return 1;
2380 + }
2381 +
2382 + handle = FR_init(argv[1]);
2383 + if (handle == NULL) {
2384 + printf("Error loading keys\n");
2385 + return 1;
2386 + }
2387 + ret = FR_decrypt_file(handle, argv[2], argv[3]);
2388 + if (ret != FONRSA_OK) {
2389 + printf("FR_decrypt_file returns %d\n", ret);
2390 + }
2391 + FR_end(handle);
2392 + return (int)ret;
2393 +}
2394 +
2395 +#endif
2396 +
2397 +
2398 --- /dev/null
2399 +++ b/net/rsa/fonrsa.h
2400 @@ -0,0 +1,53 @@
2401 +/*
2402 + * FONSM RSA handling library, used by fonsmcd and foncheckrsa
2403 + *
2404 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2405 + *
2406 + * This library is free software; you can redistribute it and/or modify
2407 + * it under the terms of the GNU Lesser General Public License as published by
2408 + * the Free Software Foundation; either version 2 of the License, or
2409 + * (at your option) any later version.
2410 + *
2411 + * This library is distributed in the hope that it will be useful,
2412 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2413 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2414 + * GNU Lesser General Public License for more details.
2415 + *
2416 + * You should have received a copy of the GNU Lesser General Public License
2417 + * along with this library; if not, write to the Free Software
2418 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2419 + *
2420 + * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
2421 + *
2422 + * $Id: fonrsa.h 404 2007-09-17 10:41:31Z jesus.pico $
2423 + */
2424 +#ifndef _FONRSA_H
2425 +#define _FONRSA_H
2426 +
2427 +#define MINIMUM_PADING_BYTES_PKCS_1_5 3
2428 +
2429 +typedef enum {
2430 + FONRSA_OK = 0,
2431 + FONRSA_VERIFICATION_FAILURE = 1,
2432 + FONRSA_OPENKEY = 2,
2433 + FONRSA_SIZE = 3,
2434 + FONRSA_LOADFILE = 4,
2435 + FONRSA_CRYPT = 5,
2436 + FONRSA_DECRYPT = 6,
2437 + FONRSA_SAVEFILE = 7,
2438 + FONRSA_NOSYS = 8,
2439 + FONRSA_VERIFY = 9
2440 +} FONRSA_ERROR;
2441 +
2442 +void *FR_init(char *public_key_path);
2443 +FONRSA_ERROR FR_end(void *handle);
2444 +FONRSA_ERROR FR_decrypt_buffer(void *handler, unsigned char *cryptext, int cryptext_size,
2445 + unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size);
2446 +FONRSA_ERROR FR_decrypt_buffer_v2(void *handler, unsigned char *cryptext, int cryptext_size,
2447 + unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size);
2448 +FONRSA_ERROR FR_verify_file(void *handler, char *file_path, char *signature_file_path);
2449 +FONRSA_ERROR FR_decrypt_file(void *handler, char *crypted_file_path, char *plaintext_file_path);
2450 +
2451 +#endif
2452 +
2453 +
2454 --- /dev/null
2455 +++ b/net/rsa/log.c
2456 @@ -0,0 +1,138 @@
2457 +/*
2458 + * Fonsm log module. Used inside the fonsm backend module and on the client.
2459 + *
2460 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2461 + *
2462 + * Created: 20070202 Pablo Martin Medrano <pablo@fon.com>
2463 + *
2464 + * $Id: log.c 392 2007-06-25 16:24:51Z pablo.martin $
2465 + */
2466 +#include <stdio.h>
2467 +#include <string.h>
2468 +#include <stdlib.h>
2469 +#include <stdarg.h>
2470 +#include <unistd.h>
2471 +#ifndef WIN32
2472 +#include <syslog.h>
2473 +#endif
2474 +#include "log.h"
2475 +
2476 +#define MAX_SESSION_PREFIX 256
2477 +
2478 +typedef struct {
2479 + char domain[256];
2480 + LG_LEVEL watermark;
2481 + int mode;
2482 + LG_log_function_pointer function;
2483 +} ST_fslog;
2484 +
2485 +static ST_fslog fslog;
2486 +static void LG_log_string(LG_LEVEL level, const char *message);
2487 +
2488 +/*!
2489 + \brief Starts the log subsystem, redirecting glog() to stderr/syslog depending
2490 + on mode
2491 + \retval FSLOG_ERROR : FSLOG_OK if everything goes well
2492 + \param lg : handle that will be returned
2493 + \param ident : program identifier, any string
2494 + \param low_watermark : if the log level is less than this value, it will not be logged
2495 + \param mode : FSLOG_MODE_SYSLOG (log to syslog) or FSLOG_MODE_STDERR (log to stderr)
2496 +*/
2497 +FSLOG_ERROR LG_start(const char *domain, LG_LEVEL watermark, int mode,
2498 + LG_log_function_pointer log_function, int facility)
2499 +{
2500 +#ifndef WIN32
2501 + strncpy(fslog.domain, domain, MAX_LG_DOMAIN);
2502 + fslog.domain[MAX_LG_DOMAIN - 1] = '\0';
2503 + fslog.watermark = watermark;
2504 + fslog.mode = mode;
2505 + fslog.function = log_function?log_function:LG_log_string;
2506 + if (fslog.mode & LG_SYSLOG)
2507 + openlog(domain, LOG_NDELAY, facility);
2508 + return FSLOG_OK;
2509 +#else
2510 + return FSLOG_OK;
2511 +#endif
2512 +}
2513 +
2514 +/*!
2515 + \brief Set the low watermark
2516 + \retval FSLOG_ERROR : FSLOG_OK
2517 + \param lg : log handle
2518 + \param low_watermark : new watermark
2519 +*/
2520 +FSLOG_ERROR LG_set_loglevel(LG_LEVEL watermark)
2521 +{
2522 + fslog.watermark = watermark;
2523 + return FSLOG_OK;
2524 +}
2525 +
2526 +/*!
2527 + \brief Ends the log subsystem, unregisteing glog handle
2528 + \retval FSLOG_ERROR : FSLOG_OK if everything goes well
2529 + \param handle : log handle to free
2530 +*/
2531 +FSLOG_ERROR LG_end(void)
2532 +{
2533 +#ifndef WIN32
2534 + if (fslog.mode & LG_SYSLOG)
2535 + closelog();
2536 +#endif
2537 + return FSLOG_OK;
2538 +}
2539 +
2540 +
2541 +void LG_log(LG_LEVEL loglevel, const char *message, ...)
2542 +{
2543 +#ifndef WIN32
2544 + va_list ap;
2545 + char buffer[4096];
2546 + int n;
2547 +
2548 + va_start(ap, message);
2549 + n = vsnprintf(buffer, MAX_LOG_STRING, message, ap);
2550 + va_end(ap);
2551 + if (n > -1 && n < MAX_LOG_STRING)
2552 + fslog.function(loglevel, buffer);
2553 + else
2554 + fon_critical("%s: Message too big to be logged", __FUNCTION__);
2555 +#else
2556 + return;
2557 +#endif
2558 +}
2559 +
2560 +/* Default log function (when mode is LG_SYSLOG or LG_STDERR) */
2561 +static void LG_log_string(LG_LEVEL level, const char *message)
2562 +{
2563 +#ifndef WIN32
2564 + static struct {
2565 + int syslog_level;
2566 + char *log_string;
2567 + } fonlog_to_syslog[] = {
2568 + [LG_DEBUG] = {LOG_ERR, "DEBUG"},
2569 + [LG_MESSAGE] = {LOG_ERR, "MESSAGE"},
2570 + [LG_WARNING] = {LOG_ERR, "WARNING"},
2571 + [LG_CRITICAL] = {LOG_ERR, "CRITICAL"},
2572 + [LG_ERROR] = {LOG_ERR, "ERROR"}
2573 + };
2574 +
2575 + if (level < fslog.watermark)
2576 + return;
2577 + if (fslog.mode & LG_SYSLOG) {
2578 + if (level == LG_MESSAGE) {
2579 + syslog(LOG_INFO, "%s", message);
2580 + } else {
2581 + syslog(fonlog_to_syslog[level].syslog_level, "%s: %s", fonlog_to_syslog[level].log_string, message);
2582 + }
2583 + }
2584 + if (fslog.mode & LG_STDERR) {
2585 + fprintf(stderr, "%s[%d]: %8.8s: %s\n", fslog.domain,
2586 + getpid(), fonlog_to_syslog[level].log_string,
2587 + message);
2588 + }
2589 +#else
2590 + /* FIXE: todo */
2591 + return;
2592 +#endif
2593 +}
2594 +
2595 --- /dev/null
2596 +++ b/net/rsa/log.h
2597 @@ -0,0 +1,77 @@
2598 +/*
2599 + * Fonsm log module. Used inside the fonsm backend module and on the client.
2600 + *
2601 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2602 + *
2603 + * Created: 20070202 Pablo Martin Medrano <pablo@fon.com>
2604 + *
2605 + * $Id: log.h 379 2007-05-28 09:17:48Z pablo.martin $
2606 + */
2607 +#ifndef _LOG_H
2608 +#define _LOG_H
2609 +
2610 +#ifdef __cplusplus
2611 +extern "C" {
2612 +#endif
2613 +
2614 +#include <stdarg.h>
2615 +
2616 +typedef enum {
2617 + FSLOG_OK = 0,
2618 + FSLOG_UNKNOWN = -1
2619 +} FSLOG_ERROR;
2620 +
2621 +
2622 +typedef void * LG_HANDLE;
2623 +
2624 +typedef enum {
2625 + LG_DEBUG = 0,
2626 + LG_MESSAGE = 1,
2627 + LG_INFO = 2,
2628 + LG_WARNING = 3,
2629 + LG_CRITICAL = 4,
2630 + LG_ERROR = 5
2631 +} LG_LEVEL;
2632 +
2633 +#define LG_SYSLOG 0x01
2634 +#define LG_STDERR 0x02
2635 +#define LG_CUSTOM 0x04
2636 +
2637 +#define MAX_LG_DOMAIN 256
2638 +#define MAX_LOG_STRING 4096
2639 +
2640 +#ifndef NDEBUG
2641 +#ifndef LOGPRINTF
2642 +#define fon_debug(...) LG_log (LG_DEBUG, __VA_ARGS__)
2643 +#else
2644 +#define fon_debug(...) { printf("DEBUG: "); printf(__VA_ARGS__); printf("\n"); }
2645 +#endif
2646 +#else
2647 +/* fon_debug evaluates to nothing when NDEBUG is defined */
2648 +#define fon_debug(...)
2649 +#endif
2650 +#ifndef LOGPRINTF
2651 +#define fon_message(...) LG_log (LG_MESSAGE, __VA_ARGS__)
2652 +#define fon_warning(...) LG_log (LG_WARNING, __VA_ARGS__)
2653 +#define fon_critical(...) LG_log (LG_CRITICAL, __VA_ARGS__)
2654 +#define fon_error(...) LG_log (LG_ERROR, __VA_ARGS__)
2655 +#else
2656 +#define fon_message(...) { printf("MESSAGE: "); printf(__VA_ARGS__); printf("\n"); }
2657 +#define fon_warning(...) { printf("WARNING: "); printf(__VA_ARGS__); printf("\n"); }
2658 +#define fon_critical(...) { printf("CRITICAL: "); printf(__VA_ARGS__); printf("\n"); }
2659 +#define fon_error(...) { printf("ERROR: "); printf(__VA_ARGS__); printf("\n"); }
2660 +#endif
2661 +
2662 +typedef void (*LG_log_function_pointer)(LG_LEVEL level, const char *message);
2663 +
2664 +FSLOG_ERROR LG_start(const char *domain, LG_LEVEL watermark, int mode, LG_log_function_pointer log_function, int facility);
2665 +FSLOG_ERROR LG_set_loglevel(LG_LEVEL watermark);
2666 +FSLOG_ERROR LG_end(void);
2667 +void LG_log(LG_LEVEL loglevel, const char *message, ...);
2668 +
2669 +#ifdef __cplusplus
2670 +}
2671 +#endif
2672 +
2673 +#endif
2674 +
2675 --- /dev/null
2676 +++ b/net/rsa/Makefile
2677 @@ -0,0 +1,31 @@
2678 +#
2679 +# FONRSA & FONSIGN libraries unit testing
2680 +#
2681 +# This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2682 +#
2683 +# Execute in this directory
2684 +#
2685 +# Created: 20070422 Pablo Martin Medrano <pablo@fon.com>
2686 +#
2687 +# $Id: Makefile 389 2007-06-11 08:29:56Z pablo.martin $
2688 +#
2689 +# FIXME: Put this in the main Makefile.am
2690 +#
2691 +all: fonsign dump_key
2692 +
2693 +fonsign:
2694 + gcc -g sign_openssl.c -D__MAINTEST__ -o fonsign -lssl
2695 +
2696 +dump_key:
2697 + gcc -o dump_key dump_key.c
2698 + ./dump_key > public_key.h
2699 +
2700 +foncheckrsa:
2701 + gcc -g bigint.c fonrsa.c rmd160.c foncheckrsa.c base64.c log.c -o foncheckrsa
2702 +
2703 +#private_fon_rsa_key.pem:
2704 +# openssl genrsa -out private_fon_rsa_key.pem 4096
2705 +# openssl rsa -in private_fon_rsa_key.pem -pubout -out public_fon_rsa_key.pem
2706 +
2707 +clean:
2708 + rm fonsign dump_key
2709 --- /dev/null
2710 +++ b/net/rsa/public_key.h
2711 @@ -0,0 +1,52 @@
2712 +unsigned char public_key[] = {
2713 + 0x2D,0x2D,0x2D,0x2D,0x2D,0x42,0x45,0x47,0x49,0x4E,0x20,0x50,0x55,0x42,0x4C,0x49,
2714 + 0x43,0x20,0x4B,0x45,0x59,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,0x4D,0x49,0x49,0x43,0x49,
2715 + 0x6A,0x41,0x4E,0x42,0x67,0x6B,0x71,0x68,0x6B,0x69,0x47,0x39,0x77,0x30,0x42,0x41,
2716 + 0x51,0x45,0x46,0x41,0x41,0x4F,0x43,0x41,0x67,0x38,0x41,0x4D,0x49,0x49,0x43,0x43,
2717 + 0x67,0x4B,0x43,0x41,0x67,0x45,0x41,0x34,0x4C,0x42,0x76,0x59,0x43,0x4B,0x38,0x38,
2718 + 0x6D,0x75,0x57,0x61,0x73,0x31,0x4F,0x53,0x73,0x71,0x30,0x0A,0x38,0x39,0x38,0x79,
2719 + 0x76,0x54,0x4B,0x71,0x41,0x6E,0x4F,0x37,0x78,0x2F,0x44,0x53,0x57,0x72,0x46,0x53,
2720 + 0x30,0x42,0x72,0x47,0x53,0x51,0x31,0x52,0x69,0x44,0x39,0x55,0x62,0x78,0x77,0x6F,
2721 + 0x64,0x76,0x36,0x65,0x51,0x4B,0x55,0x30,0x67,0x36,0x52,0x6B,0x2F,0x39,0x54,0x70,
2722 + 0x4C,0x6E,0x4F,0x2F,0x76,0x51,0x4B,0x70,0x69,0x41,0x30,0x30,0x0A,0x2B,0x32,0x59,
2723 + 0x30,0x74,0x6B,0x4C,0x39,0x73,0x6A,0x37,0x64,0x33,0x57,0x4B,0x47,0x39,0x62,0x6A,
2724 + 0x64,0x51,0x58,0x2F,0x43,0x49,0x35,0x57,0x46,0x42,0x42,0x64,0x77,0x57,0x73,0x74,
2725 + 0x4D,0x43,0x38,0x77,0x74,0x4C,0x6A,0x6A,0x45,0x59,0x79,0x43,0x58,0x46,0x32,0x31,
2726 + 0x30,0x39,0x7A,0x31,0x47,0x54,0x4C,0x73,0x53,0x44,0x34,0x57,0x4F,0x0A,0x45,0x50,
2727 + 0x6D,0x45,0x37,0x34,0x63,0x6E,0x6F,0x35,0x78,0x53,0x43,0x71,0x71,0x33,0x74,0x54,
2728 + 0x49,0x6D,0x38,0x50,0x78,0x49,0x77,0x54,0x46,0x6D,0x46,0x6F,0x6D,0x6A,0x76,0x31,
2729 + 0x4F,0x56,0x50,0x32,0x73,0x42,0x49,0x70,0x35,0x4E,0x2B,0x59,0x6F,0x56,0x61,0x53,
2730 + 0x58,0x6A,0x47,0x66,0x4E,0x63,0x54,0x36,0x4E,0x6B,0x39,0x76,0x6B,0x56,0x0A,0x57,
2731 + 0x69,0x67,0x39,0x30,0x71,0x50,0x4E,0x4C,0x58,0x6E,0x39,0x39,0x50,0x78,0x48,0x61,
2732 + 0x49,0x31,0x36,0x52,0x7A,0x78,0x48,0x4C,0x39,0x54,0x42,0x2B,0x50,0x43,0x33,0x68,
2733 + 0x33,0x61,0x58,0x33,0x71,0x57,0x30,0x4B,0x4C,0x4A,0x41,0x66,0x6F,0x35,0x70,0x48,
2734 + 0x6C,0x39,0x79,0x75,0x55,0x70,0x37,0x66,0x46,0x65,0x6A,0x4A,0x2B,0x41,0x58,0x0A,
2735 + 0x51,0x4F,0x4A,0x62,0x53,0x45,0x67,0x56,0x74,0x76,0x72,0x68,0x44,0x39,0x73,0x55,
2736 + 0x6D,0x4B,0x30,0x74,0x36,0x63,0x51,0x44,0x65,0x32,0x32,0x4E,0x4E,0x6E,0x77,0x37,
2737 + 0x43,0x4F,0x4F,0x61,0x59,0x49,0x57,0x55,0x55,0x6A,0x79,0x6A,0x68,0x35,0x50,0x4B,
2738 + 0x64,0x64,0x45,0x4B,0x5A,0x38,0x68,0x62,0x62,0x47,0x65,0x61,0x5A,0x4A,0x6F,0x76,
2739 + 0x0A,0x63,0x6F,0x51,0x64,0x55,0x56,0x51,0x6D,0x71,0x44,0x53,0x2B,0x6B,0x63,0x2F,
2740 + 0x41,0x51,0x6C,0x65,0x55,0x36,0x68,0x51,0x6A,0x63,0x55,0x4C,0x57,0x44,0x6B,0x4E,
2741 + 0x2F,0x6F,0x4F,0x6C,0x33,0x43,0x53,0x65,0x70,0x67,0x54,0x37,0x6B,0x67,0x73,0x52,
2742 + 0x63,0x63,0x47,0x74,0x66,0x4B,0x65,0x37,0x77,0x4D,0x70,0x35,0x66,0x59,0x4A,0x2B,
2743 + 0x41,0x0A,0x43,0x46,0x44,0x41,0x6F,0x4C,0x6E,0x58,0x4E,0x6A,0x4E,0x56,0x6C,0x65,
2744 + 0x73,0x43,0x6B,0x78,0x74,0x6A,0x62,0x4C,0x62,0x49,0x72,0x66,0x32,0x6E,0x43,0x62,
2745 + 0x32,0x61,0x4D,0x65,0x64,0x31,0x5A,0x48,0x4E,0x4A,0x51,0x75,0x6F,0x4E,0x58,0x67,
2746 + 0x72,0x43,0x41,0x44,0x31,0x71,0x2B,0x58,0x6E,0x66,0x77,0x63,0x69,0x6D,0x57,0x50,
2747 + 0x64,0x51,0x0A,0x44,0x59,0x6A,0x6D,0x65,0x44,0x70,0x35,0x77,0x36,0x41,0x4A,0x33,
2748 + 0x2F,0x35,0x59,0x39,0x55,0x74,0x78,0x47,0x34,0x72,0x51,0x72,0x61,0x68,0x78,0x53,
2749 + 0x42,0x77,0x43,0x4B,0x57,0x39,0x4B,0x79,0x53,0x31,0x71,0x53,0x76,0x73,0x37,0x7A,
2750 + 0x59,0x2F,0x52,0x59,0x37,0x4A,0x66,0x36,0x63,0x56,0x6B,0x54,0x43,0x78,0x69,0x33,
2751 + 0x7A,0x32,0x53,0x0A,0x50,0x46,0x33,0x51,0x64,0x6B,0x30,0x50,0x44,0x2F,0x73,0x2B,
2752 + 0x6B,0x77,0x39,0x71,0x4F,0x4E,0x79,0x69,0x33,0x67,0x6E,0x61,0x42,0x46,0x6E,0x54,
2753 + 0x77,0x48,0x7A,0x59,0x69,0x77,0x34,0x2F,0x77,0x6A,0x46,0x33,0x64,0x47,0x68,0x47,
2754 + 0x4E,0x6B,0x78,0x36,0x70,0x63,0x4E,0x4F,0x52,0x55,0x46,0x4E,0x65,0x4F,0x7A,0x59,
2755 + 0x76,0x39,0x6F,0x6A,0x0A,0x51,0x59,0x70,0x73,0x55,0x31,0x33,0x6A,0x6D,0x30,0x33,
2756 + 0x42,0x6F,0x45,0x2B,0x42,0x31,0x64,0x38,0x50,0x47,0x75,0x57,0x2B,0x49,0x7A,0x2F,
2757 + 0x41,0x4F,0x44,0x7A,0x6B,0x6F,0x56,0x6B,0x39,0x2B,0x57,0x79,0x49,0x33,0x37,0x50,
2758 + 0x30,0x53,0x7A,0x47,0x4B,0x72,0x2B,0x53,0x33,0x72,0x72,0x74,0x61,0x50,0x6C,0x41,
2759 + 0x70,0x71,0x4B,0x48,0x55,0x0A,0x6E,0x64,0x35,0x6C,0x30,0x63,0x76,0x75,0x59,0x66,
2760 + 0x31,0x4C,0x37,0x45,0x52,0x75,0x49,0x58,0x64,0x47,0x4C,0x6A,0x30,0x43,0x41,0x77,
2761 + 0x45,0x41,0x41,0x51,0x3D,0x3D,0x0A,0x2D,0x2D,0x2D,0x2D,0x2D,0x45,0x4E,0x44,0x20,
2762 + 0x50,0x55,0x42,0x4C,0x49,0x43,0x20,0x4B,0x45,0x59,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,
2763 + };
2764 --- /dev/null
2765 +++ b/net/rsa/rmd160.c
2766 @@ -0,0 +1,292 @@
2767 +/********************************************************************\
2768 + *
2769 + * FILE: rmd160.c
2770 + *
2771 + * CONTENTS: A sample C-implementation of the RIPEMD-160
2772 + * hash-function.
2773 + * TARGET: any computer with an ANSI C compiler
2774 + *
2775 + * AUTHOR: Antoon Bosselaers, ESAT-COSIC
2776 + * DATE: 1 March 1996
2777 + * VERSION: 1.0
2778 + *
2779 + * Copyright (c) Katholieke Universiteit Leuven
2780 + * 1996, All Rights Reserved
2781 + *
2782 + * Conditions for use of the RIPEMD-160 Software
2783 + *
2784 + * The RIPEMD-160 software is freely available for use under the terms and
2785 + * conditions described hereunder, which shall be deemed to be accepted by
2786 + * any user of the software and applicable on any use of the software:
2787 + *
2788 + * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
2789 + * all purposes be considered the owner of the RIPEMD-160 software and of
2790 + * all copyright, trade secret, patent or other intellectual property
2791 + * rights therein.
2792 + * 2. The RIPEMD-160 software is provided on an "as is" basis without
2793 + * warranty of any sort, express or implied. K.U.Leuven makes no
2794 + * representation that the use of the software will not infringe any
2795 + * patent or proprietary right of third parties. User will indemnify
2796 + * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
2797 + * which may arise as a result of its use of the software. In no
2798 + * circumstances K.U.Leuven R&D will be held liable for any deficiency,
2799 + * fault or other mishappening with regard to the use or performance of
2800 + * the software.
2801 + * 3. User agrees to give due credit to K.U.Leuven in scientific publications
2802 + * or communications in relation with the use of the RIPEMD-160 software
2803 + * as follows: RIPEMD-160 software written by Antoon Bosselaers,
2804 + * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
2805 + *
2806 +\********************************************************************/
2807 +
2808 +/* header files */
2809 +#include <common.h>
2810 +#include "rmd160.h"
2811 +
2812 +/********************************************************************/
2813 +
2814 +void MDinit(dword *MDbuf)
2815 +{
2816 + MDbuf[0] = 0x67452301UL;
2817 + MDbuf[1] = 0xefcdab89UL;
2818 + MDbuf[2] = 0x98badcfeUL;
2819 + MDbuf[3] = 0x10325476UL;
2820 + MDbuf[4] = 0xc3d2e1f0UL;
2821 +
2822 + return;
2823 +}
2824 +
2825 +/********************************************************************/
2826 +
2827 +void compress(dword *MDbuf, dword *X)
2828 +{
2829 + dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
2830 + dd = MDbuf[3], ee = MDbuf[4];
2831 + dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
2832 + ddd = MDbuf[3], eee = MDbuf[4];
2833 +
2834 + /* round 1 */
2835 + FF(aa, bb, cc, dd, ee, X[ 0], 11);
2836 + FF(ee, aa, bb, cc, dd, X[ 1], 14);
2837 + FF(dd, ee, aa, bb, cc, X[ 2], 15);
2838 + FF(cc, dd, ee, aa, bb, X[ 3], 12);
2839 + FF(bb, cc, dd, ee, aa, X[ 4], 5);
2840 + FF(aa, bb, cc, dd, ee, X[ 5], 8);
2841 + FF(ee, aa, bb, cc, dd, X[ 6], 7);
2842 + FF(dd, ee, aa, bb, cc, X[ 7], 9);
2843 + FF(cc, dd, ee, aa, bb, X[ 8], 11);
2844 + FF(bb, cc, dd, ee, aa, X[ 9], 13);
2845 + FF(aa, bb, cc, dd, ee, X[10], 14);
2846 + FF(ee, aa, bb, cc, dd, X[11], 15);
2847 + FF(dd, ee, aa, bb, cc, X[12], 6);
2848 + FF(cc, dd, ee, aa, bb, X[13], 7);
2849 + FF(bb, cc, dd, ee, aa, X[14], 9);
2850 + FF(aa, bb, cc, dd, ee, X[15], 8);
2851 +
2852 + /* round 2 */
2853 + GG(ee, aa, bb, cc, dd, X[ 7], 7);
2854 + GG(dd, ee, aa, bb, cc, X[ 4], 6);
2855 + GG(cc, dd, ee, aa, bb, X[13], 8);
2856 + GG(bb, cc, dd, ee, aa, X[ 1], 13);
2857 + GG(aa, bb, cc, dd, ee, X[10], 11);
2858 + GG(ee, aa, bb, cc, dd, X[ 6], 9);
2859 + GG(dd, ee, aa, bb, cc, X[15], 7);
2860 + GG(cc, dd, ee, aa, bb, X[ 3], 15);
2861 + GG(bb, cc, dd, ee, aa, X[12], 7);
2862 + GG(aa, bb, cc, dd, ee, X[ 0], 12);
2863 + GG(ee, aa, bb, cc, dd, X[ 9], 15);
2864 + GG(dd, ee, aa, bb, cc, X[ 5], 9);
2865 + GG(cc, dd, ee, aa, bb, X[ 2], 11);
2866 + GG(bb, cc, dd, ee, aa, X[14], 7);
2867 + GG(aa, bb, cc, dd, ee, X[11], 13);
2868 + GG(ee, aa, bb, cc, dd, X[ 8], 12);
2869 +
2870 + /* round 3 */
2871 + HH(dd, ee, aa, bb, cc, X[ 3], 11);
2872 + HH(cc, dd, ee, aa, bb, X[10], 13);
2873 + HH(bb, cc, dd, ee, aa, X[14], 6);
2874 + HH(aa, bb, cc, dd, ee, X[ 4], 7);
2875 + HH(ee, aa, bb, cc, dd, X[ 9], 14);
2876 + HH(dd, ee, aa, bb, cc, X[15], 9);
2877 + HH(cc, dd, ee, aa, bb, X[ 8], 13);
2878 + HH(bb, cc, dd, ee, aa, X[ 1], 15);
2879 + HH(aa, bb, cc, dd, ee, X[ 2], 14);
2880 + HH(ee, aa, bb, cc, dd, X[ 7], 8);
2881 + HH(dd, ee, aa, bb, cc, X[ 0], 13);
2882 + HH(cc, dd, ee, aa, bb, X[ 6], 6);
2883 + HH(bb, cc, dd, ee, aa, X[13], 5);
2884 + HH(aa, bb, cc, dd, ee, X[11], 12);
2885 + HH(ee, aa, bb, cc, dd, X[ 5], 7);
2886 + HH(dd, ee, aa, bb, cc, X[12], 5);
2887 +
2888 + /* round 4 */
2889 + II(cc, dd, ee, aa, bb, X[ 1], 11);
2890 + II(bb, cc, dd, ee, aa, X[ 9], 12);
2891 + II(aa, bb, cc, dd, ee, X[11], 14);
2892 + II(ee, aa, bb, cc, dd, X[10], 15);
2893 + II(dd, ee, aa, bb, cc, X[ 0], 14);
2894 + II(cc, dd, ee, aa, bb, X[ 8], 15);
2895 + II(bb, cc, dd, ee, aa, X[12], 9);
2896 + II(aa, bb, cc, dd, ee, X[ 4], 8);
2897 + II(ee, aa, bb, cc, dd, X[13], 9);
2898 + II(dd, ee, aa, bb, cc, X[ 3], 14);
2899 + II(cc, dd, ee, aa, bb, X[ 7], 5);
2900 + II(bb, cc, dd, ee, aa, X[15], 6);
2901 + II(aa, bb, cc, dd, ee, X[14], 8);
2902 + II(ee, aa, bb, cc, dd, X[ 5], 6);
2903 + II(dd, ee, aa, bb, cc, X[ 6], 5);
2904 + II(cc, dd, ee, aa, bb, X[ 2], 12);
2905 +
2906 + /* round 5 */
2907 + JJ(bb, cc, dd, ee, aa, X[ 4], 9);
2908 + JJ(aa, bb, cc, dd, ee, X[ 0], 15);
2909 + JJ(ee, aa, bb, cc, dd, X[ 5], 5);
2910 + JJ(dd, ee, aa, bb, cc, X[ 9], 11);
2911 + JJ(cc, dd, ee, aa, bb, X[ 7], 6);
2912 + JJ(bb, cc, dd, ee, aa, X[12], 8);
2913 + JJ(aa, bb, cc, dd, ee, X[ 2], 13);
2914 + JJ(ee, aa, bb, cc, dd, X[10], 12);
2915 + JJ(dd, ee, aa, bb, cc, X[14], 5);
2916 + JJ(cc, dd, ee, aa, bb, X[ 1], 12);
2917 + JJ(bb, cc, dd, ee, aa, X[ 3], 13);
2918 + JJ(aa, bb, cc, dd, ee, X[ 8], 14);
2919 + JJ(ee, aa, bb, cc, dd, X[11], 11);
2920 + JJ(dd, ee, aa, bb, cc, X[ 6], 8);
2921 + JJ(cc, dd, ee, aa, bb, X[15], 5);
2922 + JJ(bb, cc, dd, ee, aa, X[13], 6);
2923 +
2924 + /* parallel round 1 */
2925 + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
2926 + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
2927 + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
2928 + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
2929 + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
2930 + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
2931 + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
2932 + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
2933 + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
2934 + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
2935 + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
2936 + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
2937 + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
2938 + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
2939 + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
2940 + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
2941 +
2942 + /* parallel round 2 */
2943 + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
2944 + III(ddd, eee, aaa, bbb, ccc, X[11], 13);
2945 + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
2946 + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
2947 + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
2948 + III(eee, aaa, bbb, ccc, ddd, X[13], 8);
2949 + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
2950 + III(ccc, ddd, eee, aaa, bbb, X[10], 11);
2951 + III(bbb, ccc, ddd, eee, aaa, X[14], 7);
2952 + III(aaa, bbb, ccc, ddd, eee, X[15], 7);
2953 + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
2954 + III(ddd, eee, aaa, bbb, ccc, X[12], 7);
2955 + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
2956 + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
2957 + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
2958 + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
2959 +
2960 + /* parallel round 3 */
2961 + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
2962 + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
2963 + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
2964 + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
2965 + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
2966 + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
2967 + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
2968 + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
2969 + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
2970 + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
2971 + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
2972 + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
2973 + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
2974 + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
2975 + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
2976 + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
2977 +
2978 + /* parallel round 4 */
2979 + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
2980 + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
2981 + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
2982 + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
2983 + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
2984 + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
2985 + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
2986 + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
2987 + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
2988 + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
2989 + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
2990 + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
2991 + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
2992 + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
2993 + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
2994 + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
2995 +
2996 + /* parallel round 5 */
2997 + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
2998 + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
2999 + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
3000 + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
3001 + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
3002 + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
3003 + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
3004 + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
3005 + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
3006 + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
3007 + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
3008 + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
3009 + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
3010 + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
3011 + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
3012 + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
3013 +
3014 + /* combine results */
3015 + ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
3016 + MDbuf[1] = MDbuf[2] + dd + eee;
3017 + MDbuf[2] = MDbuf[3] + ee + aaa;
3018 + MDbuf[3] = MDbuf[4] + aa + bbb;
3019 + MDbuf[4] = MDbuf[0] + bb + ccc;
3020 + MDbuf[0] = ddd;
3021 +
3022 + return;
3023 +}
3024 +
3025 +/********************************************************************/
3026 +
3027 +void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen)
3028 +{
3029 + unsigned int i; /* counter */
3030 + dword X[16]; /* message words */
3031 +
3032 + memset(X, 0, 16*sizeof(dword));
3033 +
3034 + /* put bytes from strptr into X */
3035 + for (i=0; i<(lswlen&63); i++) {
3036 + /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
3037 + X[i>>2] ^= (dword) *strptr++ << (8 * (i&3));
3038 + }
3039 +
3040 + /* append the bit m_n == 1 */
3041 + X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7);
3042 +
3043 + if ((lswlen & 63) > 55) {
3044 + /* length goes to next block */
3045 + compress(MDbuf, X);
3046 + memset(X, 0, 16*sizeof(dword));
3047 + }
3048 +
3049 + /* append length in bits*/
3050 + X[14] = lswlen << 3;
3051 + X[15] = (lswlen >> 29) | (mswlen << 3);
3052 + compress(MDbuf, X);
3053 +
3054 + return;
3055 +}
3056 +
3057 +/************************ end of file rmd160.c **********************/
3058 +
3059 --- /dev/null
3060 +++ b/net/rsa/rmd160.h
3061 @@ -0,0 +1,154 @@
3062 +/********************************************************************\
3063 + *
3064 + * FILE: rmd160.h
3065 + *
3066 + * CONTENTS: Header file for a sample C-implementation of the
3067 + * RIPEMD-160 hash-function.
3068 + * TARGET: any computer with an ANSI C compiler
3069 + *
3070 + * AUTHOR: Antoon Bosselaers, ESAT-COSIC
3071 + * DATE: 1 March 1996
3072 + * VERSION: 1.0
3073 + *
3074 + * Copyright (c) Katholieke Universiteit Leuven
3075 + * 1996, All Rights Reserved
3076 + *
3077 + * Conditions for use of the RIPEMD-160 Software
3078 + *
3079 + * The RIPEMD-160 software is freely available for use under the terms and
3080 + * conditions described hereunder, which shall be deemed to be accepted by
3081 + * any user of the software and applicable on any use of the software:
3082 + *
3083 + * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
3084 + * all purposes be considered the owner of the RIPEMD-160 software and of
3085 + * all copyright, trade secret, patent or other intellectual property
3086 + * rights therein.
3087 + * 2. The RIPEMD-160 software is provided on an "as is" basis without
3088 + * warranty of any sort, express or implied. K.U.Leuven makes no
3089 + * representation that the use of the software will not infringe any
3090 + * patent or proprietary right of third parties. User will indemnify
3091 + * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
3092 + * which may arise as a result of its use of the software. In no
3093 + * circumstances K.U.Leuven R&D will be held liable for any deficiency,
3094 + * fault or other mishappening with regard to the use or performance of
3095 + * the software.
3096 + * 3. User agrees to give due credit to K.U.Leuven in scientific publications
3097 + * or communications in relation with the use of the RIPEMD-160 software
3098 + * as follows: RIPEMD-160 software written by Antoon Bosselaers,
3099 + * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
3100 + *
3101 +\********************************************************************/
3102 +
3103 +#ifndef RMD160H /* make sure this file is read only once */
3104 +#define RMD160H
3105 +
3106 +/********************************************************************/
3107 +
3108 +/* typedef 8 and 32 bit types, resp. */
3109 +/* adapt these, if necessary,
3110 + for your operating system and compiler */
3111 +typedef unsigned char byte;
3112 +typedef unsigned long dword;
3113 +
3114 +
3115 +/********************************************************************/
3116 +
3117 +/* macro definitions */
3118 +
3119 +/* collect four bytes into one word: */
3120 +#define BYTES_TO_DWORD(strptr) \
3121 + (((dword) *((strptr)+3) << 24) | \
3122 + ((dword) *((strptr)+2) << 16) | \
3123 + ((dword) *((strptr)+1) << 8) | \
3124 + ((dword) *(strptr)))
3125 +
3126 +/* ROL(x, n) cyclically rotates x over n bits to the left */
3127 +/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
3128 +#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
3129 +
3130 +/* the five basic functions F(), G() and H() */
3131 +#define F(x, y, z) ((x) ^ (y) ^ (z))
3132 +#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
3133 +#define H(x, y, z) (((x) | ~(y)) ^ (z))
3134 +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
3135 +#define J(x, y, z) ((x) ^ ((y) | ~(z)))
3136 +
3137 +/* the ten basic operations FF() through III() */
3138 +#define FF(a, b, c, d, e, x, s) {\
3139 + (a) += F((b), (c), (d)) + (x);\
3140 + (a) = ROL((a), (s)) + (e);\
3141 + (c) = ROL((c), 10);\
3142 + }
3143 +#define GG(a, b, c, d, e, x, s) {\
3144 + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
3145 + (a) = ROL((a), (s)) + (e);\
3146 + (c) = ROL((c), 10);\
3147 + }
3148 +#define HH(a, b, c, d, e, x, s) {\
3149 + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
3150 + (a) = ROL((a), (s)) + (e);\
3151 + (c) = ROL((c), 10);\
3152 + }
3153 +#define II(a, b, c, d, e, x, s) {\
3154 + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
3155 + (a) = ROL((a), (s)) + (e);\
3156 + (c) = ROL((c), 10);\
3157 + }
3158 +#define JJ(a, b, c, d, e, x, s) {\
3159 + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
3160 + (a) = ROL((a), (s)) + (e);\
3161 + (c) = ROL((c), 10);\
3162 + }
3163 +#define FFF(a, b, c, d, e, x, s) {\
3164 + (a) += F((b), (c), (d)) + (x);\
3165 + (a) = ROL((a), (s)) + (e);\
3166 + (c) = ROL((c), 10);\
3167 + }
3168 +#define GGG(a, b, c, d, e, x, s) {\
3169 + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
3170 + (a) = ROL((a), (s)) + (e);\
3171 + (c) = ROL((c), 10);\
3172 + }
3173 +#define HHH(a, b, c, d, e, x, s) {\
3174 + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
3175 + (a) = ROL((a), (s)) + (e);\
3176 + (c) = ROL((c), 10);\
3177 + }
3178 +#define III(a, b, c, d, e, x, s) {\
3179 + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
3180 + (a) = ROL((a), (s)) + (e);\
3181 + (c) = ROL((c), 10);\
3182 + }
3183 +#define JJJ(a, b, c, d, e, x, s) {\
3184 + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
3185 + (a) = ROL((a), (s)) + (e);\
3186 + (c) = ROL((c), 10);\
3187 + }
3188 +
3189 +/********************************************************************/
3190 +
3191 +/* function prototypes */
3192 +
3193 +void MDinit(dword *MDbuf);
3194 +/*
3195 + * initializes MDbuffer to "magic constants"
3196 + */
3197 +
3198 +void compress(dword *MDbuf, dword *X);
3199 +/*
3200 + * the compression function.
3201 + * transforms MDbuf using message bytes X[0] through X[15]
3202 + */
3203 +
3204 +void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen);
3205 +/*
3206 + * puts bytes from strptr into X and pad out; appends length
3207 + * and finally, compresses the last block(s)
3208 + * note: length in bits == 8 * (lswlen + 2^32 mswlen).
3209 + * note: there are (lswlen mod 64) bytes left in strptr.
3210 + */
3211 +
3212 +#endif /* RMD160H */
3213 +
3214 +/*********************** end of file rmd160.h ***********************/
3215 +
3216 --- /dev/null
3217 +++ b/net/rsa/rsa.c
3218 @@ -0,0 +1,303 @@
3219 +/*
3220 + * FONSM RSA handling library
3221 + *
3222 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
3223 + *
3224 + * This library is free software; you can redistribute it and/or modify
3225 + * it under the terms of the GNU Lesser General Public License as published by
3226 + * the Free Software Foundation; either version 2 of the License, or
3227 + * (at your option) any later version.
3228 + *
3229 + * This library is distributed in the hope that it will be useful,
3230 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3231 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3232 + * GNU Lesser General Public License for more details.
3233 + *
3234 + * You should have received a copy of the GNU Lesser General Public License
3235 + * along with this library; if not, write to the Free Software
3236 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3237 + *
3238 + * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
3239 + *
3240 + * Based on axTLS
3241 + *
3242 + * $Id: fonrsa.c 405 2007-09-19 15:26:17Z jesus.pico $
3243 + */
3244 +#include <malloc.h>
3245 +#include <common.h>
3246 +#include "rsa.h"
3247 +#include "rmd160.h"
3248 +#include "bigint.h"
3249 +#include "base64.h"
3250 +
3251 +#include "public_key.h"
3252 +
3253 +#define RMDsize 160 /* A RIPEMD-160 hash has 160 bits */
3254 +
3255 +typedef struct {
3256 + uint8_t *buffer;
3257 + size_t size;
3258 +} DER_key;
3259 +
3260 +typedef struct {
3261 + bigint *m; /* modulus */
3262 + bigint *e; /* public exponent */
3263 + int num_octets;
3264 + BI_CTX *bi_ctx; /* big integer handle */
3265 +} RSA_parameters;
3266 +
3267 +typedef struct {
3268 + DER_key *derkey;
3269 + RSA_parameters *rsaparms;
3270 +} RSA;
3271 +
3272 +static void CH_free_der_key(DER_key *key)
3273 +{
3274 + free(key->buffer);
3275 + free(key);
3276 +}
3277 +
3278 +int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out)
3279 +{
3280 + bigint *dat_bi;
3281 + bigint *decrypted_bi;
3282 + int byte_size;
3283 +
3284 + byte_size = rsa->num_octets;
3285 + dat_bi = bi_import(rsa->bi_ctx, buffer_in, byte_size);
3286 + rsa->bi_ctx->mod_offset = BIGINT_M_OFFSET;
3287 + bi_copy(rsa->m);
3288 + decrypted_bi = bi_mod_power(rsa->bi_ctx, dat_bi, rsa->e);
3289 + bi_export(rsa->bi_ctx, decrypted_bi, buffer_out, byte_size);
3290 + return 0;
3291 +}
3292 +
3293 +byte *RMDbinary(char *buffer, int len)
3294 +{
3295 + byte data[1024]; /* contains current mess. block */
3296 + dword nbytes; /* length of this block */
3297 + dword MDbuf[RMDsize / 32]; /* contains (A, B, C, D(, E)) */
3298 + static byte hashcode[RMDsize / 8]; /* for final hash-value */
3299 + dword X[16]; /* current 16-word chunk */
3300 + unsigned int i, j; /* counters */
3301 + dword length[2]; /* length in bytes of message */
3302 + dword offset; /* # of unprocessed bytes at */
3303 + /* call of MDfinish */
3304 + int total = len;
3305 + char *tmp = buffer;
3306 + MDinit(MDbuf);
3307 + length[0] = 0;
3308 + length[1] = 0;
3309 + while ( len) {
3310 + memcpy(data, tmp, 1024);
3311 + if(len > 1024)
3312 + {
3313 + nbytes = 1024;
3314 + len -= 1024;
3315 + tmp += 1024;
3316 + } else {
3317 + nbytes = len;
3318 + len = 0;
3319 + }
3320 + /* process all complete blocks */
3321 + for (i = 0; i < (nbytes >> 6); i++) {
3322 + for (j = 0; j < 16; j++)
3323 + X[j] = BYTES_TO_DWORD(data + 64 * i + 4 * j);
3324 + compress(MDbuf, X);
3325 + }
3326 + /* update length[] */
3327 + if (length[0] + nbytes < length[0])
3328 + length[1]++; /* overflow to msb of length */
3329 + length[0] += nbytes;
3330 + }
3331 + /* finish: */
3332 + offset = length[0] & 0x3C0; /* extract bytes 6 to 10 inclusive */
3333 + MDfinish(MDbuf, data + offset, length[0], length[1]);
3334 +
3335 + for (i = 0; i < RMDsize / 8; i += 4) {
3336 + hashcode[i] = MDbuf[i >> 2];
3337 + hashcode[i + 1] = (MDbuf[i >> 2] >> 8);
3338 + hashcode[i + 2] = (MDbuf[i >> 2] >> 16);
3339 + hashcode[i + 3] = (MDbuf[i >> 2] >> 24);
3340 + }
3341 +
3342 + return (byte *) hashcode;
3343 +}
3344 +
3345 +static DER_key *CH_load_pem_key(void)
3346 +{
3347 + DER_key *ret;
3348 + uint8_t *buffer;
3349 + char *b64,*p,*t;
3350 + char key[1024];
3351 + size_t filesize;
3352 + int size;
3353 +
3354 + if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
3355 + return NULL;
3356 + buffer = public_key;
3357 + p = (char *)buffer;
3358 + while ((*p != '\n') && (*p != '\0'))
3359 + p++;
3360 + if (*p == '\0') {
3361 + free(ret);
3362 + return NULL;
3363 + }
3364 + p++;
3365 + b64 = t = p;
3366 + while((p - b64) <= filesize) {
3367 + if ((*p == '-')) {
3368 + break;
3369 + } else if ((*p != '\n') && (*p != ' ') && (*p != '\t')) {
3370 + *t = *p;
3371 + t++;
3372 + }
3373 + p++;
3374 + }
3375 + *t = '\0';
3376 + size = B64_decode(b64, key, strlen(b64), 1024);
3377 + if (size < 0) {
3378 + free(buffer);
3379 + free(ret);
3380 + return NULL;
3381 + }
3382 + //free(buffer);
3383 + ret->buffer = (char *)malloc(size);
3384 + ret->size = size;
3385 + memcpy((void *)ret->buffer, (void *)key, size);
3386 + return ret;
3387 +}
3388 +
3389 +/*
3390 + * Similar to RSA_pub_key_new, rewritten to make this program depend only on bi module
3391 + */
3392 +void CH_pub_key_new(RSA_parameters **rsa, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len)
3393 +{
3394 + RSA_parameters *rsa_parameters;
3395 +
3396 + BI_CTX *bi_ctx = bi_initialize();
3397 + *rsa = (RSA_parameters *)calloc(1, sizeof(RSA_parameters));
3398 + rsa_parameters = *rsa;
3399 + rsa_parameters->bi_ctx = bi_ctx;
3400 + rsa_parameters->num_octets = (mod_len & 0xFFF0);
3401 + rsa_parameters->m = bi_import(bi_ctx, modulus, mod_len);
3402 + bi_set_mod(bi_ctx, rsa_parameters->m, BIGINT_M_OFFSET);
3403 + rsa_parameters->e = bi_import(bi_ctx, pub_exp, pub_len);
3404 + bi_permanent(rsa_parameters->e);
3405 +}
3406 +
3407 +/*
3408 + * Get the public key specifics from an ASN.1 encoded file
3409 + * A function lacking in the exported axTLS API
3410 + *
3411 + * This is a really weird hack that only works with RSA public key
3412 + * files
3413 + */
3414 +static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters)
3415 +{
3416 + uint8_t *modulus, *pub_exp;
3417 + int mod_len, pub_len;
3418 +
3419 + pub_len = 3;
3420 + mod_len = len - 37;
3421 + if (buf[0] != 0x30) {
3422 + return -1;
3423 + }
3424 +
3425 + pub_exp = (uint8_t *)malloc(3);
3426 + modulus = (uint8_t *)malloc(mod_len);
3427 + memcpy(modulus, buf + 32 , mod_len);
3428 + memcpy(pub_exp, buf + 34 + mod_len, 3);
3429 + if (mod_len <= 0 || pub_len <= 0 )
3430 + return -1;
3431 + CH_pub_key_new(rsa_parameters, modulus, mod_len, pub_exp, pub_len);
3432 +
3433 + free(modulus);
3434 + free(pub_exp);
3435 + return 0;
3436 +}
3437 +
3438 +
3439 +/* FR_init */
3440 +void *FR_init(void)
3441 +{
3442 + DER_key *derkey;
3443 + RSA_parameters *rsa_parameters;
3444 +
3445 + derkey = CH_load_pem_key();
3446 + if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
3447 + fprintf(stderr, "Error: Extracting public key from file\n");
3448 + return 0;
3449 + }
3450 + CH_free_der_key(derkey);
3451 + return (void *)rsa_parameters;
3452 +}
3453 +
3454 +FONRSA_ERROR FR_end(void *handle)
3455 +{
3456 + RSA_parameters *rsa_parameters = (RSA_parameters *)handle;
3457 +
3458 + free(rsa_parameters);
3459 + return FONRSA_OK;
3460 +}
3461 +
3462 +/*
3463 + *
3464 + * Implementation of PKCS 1.5 padding, borrowed from
3465 + * Tom's code (public domain)
3466 + */
3467 +
3468 +/* Standalone FR_verify_file */
3469 +FONRSA_ERROR FR_verify_file(void *handler, char *file_data, int file_len,
3470 + char *signature_buffer, int signature_size)
3471 +{
3472 + int j;
3473 + byte *hashcode;
3474 + byte hash[20];
3475 + uint8_t *decrypted;
3476 + RSA_parameters *rsa_parameters = (RSA_parameters *)handler;
3477 +
3478 + /* Calculates the RIPEMD-160 hash of the file */
3479 + hashcode = RMDbinary (file_data, file_len);
3480 +
3481 + if (rsa_parameters->num_octets != signature_size)
3482 + return FONRSA_SIZE;
3483 + decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
3484 + if (CH_decrypt(rsa_parameters, signature_buffer, decrypted)) {
3485 + printf("Error: Decrypting signature\n");
3486 + return FONRSA_VERIFICATION_FAILURE;
3487 + }
3488 + memcpy(hash, decrypted + 492, 20);
3489 + //free(decrypted);
3490 + //free(signature_buffer);
3491 + for (j = 0; j < RMDsize/8; j++) {
3492 + if (hash[j] != hashcode[j])
3493 + return FONRSA_VERIFICATION_FAILURE;
3494 + }
3495 + return FONRSA_OK;
3496 +}
3497 +
3498 +int rsa_check_signature(char *signature, int signature_len, char *buffer, int buffer_len)
3499 +{
3500 + FONRSA_ERROR fonrsa_error;
3501 + void *handle;
3502 + handle = FR_init();
3503 + if (handle == NULL) {
3504 + printf("Error loading keys\n");
3505 + return 1;
3506 + }
3507 + fonrsa_error = FR_verify_file(handle, buffer, buffer_len, signature, signature_len);
3508 + FR_end(handle);
3509 + switch (fonrsa_error) {
3510 + case FONRSA_OK:
3511 + printf("Verified OK\n");
3512 + return 0;
3513 + case FONRSA_VERIFICATION_FAILURE:
3514 + printf("Verification failure\n");
3515 + return 1;
3516 + default:
3517 + printf("Verification error\n");
3518 + return -1;
3519 + }
3520 +
3521 +}
3522 --- /dev/null
3523 +++ b/net/rsa/rsa.h
3524 @@ -0,0 +1,46 @@
3525 +/*
3526 + * FONSM RSA handling library, used by fonsmcd and foncheckrsa
3527 + *
3528 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
3529 + *
3530 + * This library is free software; you can redistribute it and/or modify
3531 + * it under the terms of the GNU Lesser General Public License as published by
3532 + * the Free Software Foundation; either version 2 of the License, or
3533 + * (at your option) any later version.
3534 + *
3535 + * This library is distributed in the hope that it will be useful,
3536 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3537 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3538 + * GNU Lesser General Public License for more details.
3539 + *
3540 + * You should have received a copy of the GNU Lesser General Public License
3541 + * along with this library; if not, write to the Free Software
3542 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3543 + *
3544 + * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
3545 + *
3546 + * $Id: fonrsa.h 404 2007-09-17 10:41:31Z jesus.pico $
3547 + */
3548 +#ifndef _FONRSA_H
3549 +#define _FONRSA_H
3550 +
3551 +#define MINIMUM_PADING_BYTES_PKCS_1_5 3
3552 +
3553 +typedef enum {
3554 + FONRSA_OK = 0,
3555 + FONRSA_VERIFICATION_FAILURE = 1,
3556 + FONRSA_OPENKEY = 2,
3557 + FONRSA_SIZE = 3,
3558 + FONRSA_LOADFILE = 4,
3559 + FONRSA_CRYPT = 5,
3560 + FONRSA_DECRYPT = 6,
3561 + FONRSA_SAVEFILE = 7,
3562 + FONRSA_NOSYS = 8,
3563 + FONRSA_VERIFY = 9
3564 +} FONRSA_ERROR;
3565 +
3566 +int rsa_check_signature(char *signature, int signature_len, char *buffer, int buffer_len);
3567 +
3568 +#endif
3569 +
3570 +
3571 --- /dev/null
3572 +++ b/net/rsa/sign.h
3573 @@ -0,0 +1,27 @@
3574 +/*
3575 + * Signature interface
3576 + *
3577 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
3578 + *
3579 + * Created: 20070417 Pablo Martín Medrano <pablo@fon.com>
3580 + *
3581 + * $Id: sign.h 389 2007-06-11 08:29:56Z pablo.martin $
3582 + */
3583 +#ifndef __SIGN_H__
3584 +#define __SIGN_H__
3585 +#ifdef __cplusplus
3586 + extern "C" {
3587 +#endif
3588 +
3589 +void SG_init(void);
3590 +void *SG_start(char *private_key_path, char *public_key_path);
3591 +void SG_stop(void *handle);
3592 +int SG_crypt(void *data, unsigned char *text, int size_text, unsigned char *crypted_text,
3593 + unsigned int crypted_text_buffer_size, int *crypted_size);
3594 +int SG_crypt_v2(void *data, unsigned char *text, int size_text, unsigned char *crypted_text,
3595 + unsigned int crypted_text_buffer_size, int *crypted_size);
3596 +#ifdef __cplusplus
3597 +}
3598 +#endif
3599 +#endif /* #ifdef __SIGN_H__ */
3600 +
3601 --- /dev/null
3602 +++ b/net/rsa/sign_openssl.c
3603 @@ -0,0 +1,437 @@
3604 +/*
3605 + * Signature using OpenSSL
3606 + *
3607 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
3608 + *
3609 + * Created: 20070417 Pablo Martín Medrano <pablo@fon.com>
3610 + *
3611 + * $Id: sign_openssl.c 346 2007-05-10 19:51:38Z pablo.martin $
3612 + */
3613 +/*
3614 + *
3615 + * How the RSA public and private key was generated
3616 + * To check .FON files
3617 + * openssl genrsa -out private_fon_rsa_key.pem 4096
3618 + * openssl rsa -in private_fon_rsa_key.pem -pubout -out public_fon_rsa_key.pem
3619 + *
3620 + * How the Status Manager public and private key was generated
3621 + * openssl genrsa -out private_sm_rsa_key.pem 2048
3622 + * openssl rsa -in private_sm_rsa_key.pem -pubout -out public_sm_rsa_key.pem
3623 + *
3624 + * How to sign using the RSA private key (This is what fonsign does)
3625 + * openssl dgst -rmd160 -sign private_fon_rsa_key.pem FILE > SIGNATURE
3626 + * How to verify using the RSA public key (This is what fonverify + foncheckrsa does)
3627 + * openssl dgst -rmd160 -verify public_fon_rsa_key.pem -signature SIGNATURE FILE
3628 + * Convert to DER file (to use it in La Fonera)
3629 + * openssl rsa -inform PEM -outform DER -pubin -in public_fon_rsa_key.pem -pubout -out public_fon_rsa_key.der
3630 + */
3631 +#include <openssl/rsa.h>
3632 +#include <openssl/ssl.h>
3633 +#include <openssl/bn.h>
3634 +#include <openssl/pem.h>
3635 +#include <openssl/evp.h>
3636 +#include <sys/stat.h>
3637 +#include <fcntl.h>
3638 +#ifndef __MAINTEST__
3639 +#include "log.h"
3640 +#else
3641 +#define fon_warning printf
3642 +#define fon_debug printf
3643 +#define fon_critical printf
3644 +#endif
3645 +#include "sign.h"
3646 +
3647 +typedef struct {
3648 + RSA *rsa;
3649 + int rsa_size;
3650 + EVP_PKEY *pkey;
3651 + int pkey_size;
3652 + RSA *public_rsa;
3653 + int public_rsa_size;
3654 + EVP_PKEY *public_pkey;
3655 + int public_pkey_size;
3656 +} Sign;
3657 +
3658 +typedef enum {
3659 + KEY_PUBLIC = 0,
3660 + KEY_PRIVATE
3661 +} KEY_TYPE;
3662 +
3663 +static EVP_PKEY *SG_load_key(char *key_path, KEY_TYPE type);
3664 +static unsigned char *load_file_in_buffer(char *path, int *size);
3665 +static int save_file_from_buffer(char *path, char *buffer, int size);
3666 +
3667 +void SG_init(void)
3668 +{
3669 + SSL_load_error_strings();
3670 + SSL_library_init();
3671 + OpenSSL_add_all_algorithms();
3672 + OpenSSL_add_all_ciphers();
3673 + OpenSSL_add_all_digests();
3674 +}
3675 +
3676 +static unsigned char *load_file_in_buffer(char *path, int *size)
3677 +{
3678 + char *buffer;
3679 + struct stat st;
3680 + int fd;
3681 +
3682 + if (stat(path, &st))
3683 + return NULL;
3684 + buffer = (char *)malloc(st.st_size);
3685 + if (buffer == NULL)
3686 + return NULL;
3687 + if ((fd = open(path, O_RDONLY)) == -1) {
3688 + free(buffer);
3689 + return NULL;
3690 + }
3691 + if (read(fd,buffer,st.st_size) != (ssize_t)st.st_size) {
3692 + free(buffer);
3693 + close(fd);
3694 + return NULL;
3695 + }
3696 + *size = (int)st.st_size;
3697 + close(fd);
3698 + return buffer;
3699 +}
3700 +
3701 +static int save_file_from_buffer(char *path, char *buffer, int size)
3702 +{
3703 + int fd;
3704 +
3705 + if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) == -1)
3706 + return -1;
3707 + if (write(fd, buffer, (size_t)size) != ((ssize_t)size)) {
3708 + close(fd);
3709 + return -1;
3710 + }
3711 + close(fd);
3712 + return 0;
3713 +}
3714 +
3715 +static EVP_PKEY *SG_load_key(char *key_path, KEY_TYPE type)
3716 +{
3717 + BIO *key = NULL;
3718 + EVP_PKEY *pkey;
3719 +
3720 + if ((key = BIO_new(BIO_s_file())) == NULL) {
3721 + //ERR_print_errors(err);
3722 + fon_warning("%s: Error calling BIO_new()\n", __FUNCTION__);
3723 + return NULL;
3724 + }
3725 + if (BIO_read_filename(key, key_path) <= 0) {
3726 + fon_warning("%s: Error opening %s\n", __FUNCTION__, key_path);
3727 + // ERR_print_errors(err);
3728 + BIO_free(key);
3729 + }
3730 + if (type == KEY_PUBLIC) {
3731 + pkey = PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
3732 + } else if (type == KEY_PRIVATE) {
3733 + pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL);
3734 + } else {
3735 + return NULL;
3736 + }
3737 +
3738 + if (pkey == NULL) {
3739 + fon_warning("%s: Error reading %s\n", __FUNCTION__, key_path);
3740 + BIO_free(key);
3741 + return NULL;
3742 + }
3743 + BIO_free(key);
3744 + return pkey;
3745 +}
3746 +
3747 +void *SG_start(char *private_key_path, char *public_key_path)
3748 +{
3749 + Sign *sign;
3750 +
3751 + if ((sign = (Sign *)malloc(sizeof(Sign))) == NULL)
3752 + return NULL;
3753 + memset(sign, 0, sizeof(Sign));
3754 + if (private_key_path != NULL) {
3755 + if ((sign->pkey = SG_load_key(private_key_path, KEY_PRIVATE)) == NULL) {
3756 + fon_warning("%s: Error loading %s", __FUNCTION__, private_key_path);
3757 + return NULL;
3758 + }
3759 + }
3760 + if (public_key_path != NULL) {
3761 + if ((sign->public_pkey = SG_load_key(public_key_path, KEY_PUBLIC)) == NULL) {
3762 + fon_warning("%s: Error loading %s", __FUNCTION__, public_key_path);
3763 + return NULL;
3764 + }
3765 + }
3766 + if (sign->pkey != NULL) {
3767 + sign->pkey_size = EVP_PKEY_size(sign->pkey);
3768 + if ((sign->rsa = EVP_PKEY_get1_RSA(sign->pkey)) == NULL) {
3769 + EVP_PKEY_free(sign->pkey);
3770 + return NULL;
3771 + }
3772 + }
3773 + if (sign->public_pkey != NULL) {
3774 + sign->public_pkey_size = EVP_PKEY_size(sign->public_pkey);
3775 + if ((sign->public_rsa = EVP_PKEY_get1_RSA(sign->public_pkey)) == NULL) {
3776 + EVP_PKEY_free(sign->pkey);
3777 + return NULL;
3778 + }
3779 + }
3780 + if (((sign->rsa == NULL) && (private_key_path != NULL)) ||
3781 + ((sign->public_rsa == NULL) && (public_key_path != NULL))) {
3782 + fon_warning("%s: Error calling EVP_PKEY_get1_RSA()", __FUNCTION__);
3783 + return NULL;
3784 + }
3785 + if (sign->rsa != NULL) {
3786 + sign->rsa_size = RSA_size(sign->rsa);
3787 + if (RSA_check_key(sign->rsa) != 1) {
3788 + fon_warning("%s: RSA key failure", __FUNCTION__);
3789 + return NULL;
3790 + }
3791 + }
3792 +
3793 + return (void *)sign;
3794 +}
3795 +
3796 +void SG_stop(void *handle)
3797 +{
3798 + Sign *sign = (Sign *)handle;
3799 +
3800 + EVP_PKEY_free(sign->pkey);
3801 + EVP_PKEY_free(sign->public_pkey);
3802 + if (sign->rsa != NULL)
3803 + RSA_free(sign->rsa);
3804 + if (sign->public_rsa != NULL)
3805 + RSA_free(sign->public_rsa);
3806 + free(sign);
3807 +}
3808 +
3809 +int SG_verify(void *data, unsigned char *text, unsigned int size_text,
3810 + unsigned char *signature, unsigned int size_signature)
3811 +{
3812 + EVP_MD_CTX mdctx;
3813 + EVP_MD *md;
3814 + EVP_PKEY *pkey;
3815 + int ret;
3816 + Sign *sign = (Sign *)data;
3817 +
3818 + md = (EVP_MD *)EVP_ripemd160();
3819 + if(!EVP_VerifyInit(&mdctx, md))
3820 + return 4;
3821 + if (!EVP_VerifyUpdate(&mdctx, (const void *)text, (unsigned int)size_text)) {
3822 + return 5;
3823 + }
3824 + ret = EVP_VerifyFinal(&mdctx, (const char *)signature, size_signature, sign->public_pkey);
3825 + EVP_PKEY_free(pkey);
3826 + EVP_MD_CTX_cleanup(&mdctx);
3827 + return ret;
3828 +}
3829 +
3830 +int SG_sign(void *data, void *text, unsigned int size_text, void *signature_buffer,
3831 + unsigned int size_signature_buffer, unsigned int *size_signature)
3832 +{
3833 + unsigned char *digest[EVP_MAX_MD_SIZE];
3834 + EVP_MD_CTX mdctx;
3835 + EVP_MD *md;
3836 + int ret;
3837 + Sign *sign = (Sign *)data;
3838 +
3839 + if (size_signature_buffer < sign->pkey_size)
3840 + return 1;
3841 +
3842 + md = (EVP_MD *)EVP_ripemd160();
3843 + EVP_SignInit(&mdctx, md);
3844 + if (!EVP_SignUpdate(&mdctx, (const void *)text, (unsigned int)size_text)) {
3845 + return 2;
3846 + }
3847 + if (!EVP_SignFinal(&mdctx, (unsigned char *)signature_buffer, (unsigned int *)size_signature, sign->pkey)) {
3848 + return 3;
3849 + }
3850 + EVP_MD_CTX_cleanup(&mdctx);
3851 +
3852 + return 0;
3853 +}
3854 +
3855 +/*
3856 + * It's not advised to crypt using RAW ... unless you have crypted the buffer using AES before.
3857 + */
3858 +int SG_crypt(void *data, unsigned char *text, int size_text,
3859 + unsigned char *crypted_text, unsigned int crypted_text_buffer_size,
3860 + int *crypted_size)
3861 +{
3862 + EVP_MD_CTX mdctx;
3863 + EVP_MD *md;
3864 + int retsize;
3865 + Sign *sign = (Sign *)data;
3866 +
3867 + if (crypted_text_buffer_size < sign->pkey_size) {
3868 + fon_critical("%s: size_signature_buffer [%u] < %u", __FUNCTION__, size_text, sign->pkey_size);
3869 + return 1;
3870 + }
3871 + if (size_text != sign->pkey_size) {
3872 + fon_critical("%s: size_text [%u] != %u", __FUNCTION__, size_text, sign->pkey_size);
3873 + return 2;
3874 + }
3875 + /* The buffer is pre-padded with random data ... */
3876 + fon_debug("%s: About to call RSA_private_encrypt(%d, %x, %x, %x, %d)",
3877 + __FUNCTION__, size_text, crypted_text, sign->rsa, RSA_NO_PADDING);
3878 + retsize = RSA_private_encrypt(size_text, text, crypted_text, sign->rsa, RSA_NO_PADDING);
3879 + if (retsize == -1) {
3880 + fon_critical("%s: Error calling RSA_private_encrypt(%d, %x, %x, %x, %d)",
3881 + __FUNCTION__, size_text, crypted_text, sign->rsa, RSA_NO_PADDING);
3882 + return 1;
3883 + }
3884 + *crypted_size = retsize;
3885 + return 0;
3886 +}
3887 +
3888 +/* SG_decrypt */
3889 +int SG_decrypt(void *data, unsigned char *cryptext, int cryptext_size, unsigned char *plaintext,
3890 + int plaintext_buffer_size, int *plaintext_size)
3891 +{
3892 + EVP_MD_CTX mdctx;
3893 + EVP_MD *md;
3894 + int retsize;
3895 + Sign *sign = (Sign *)data;
3896 +
3897 + if (plaintext_buffer_size < sign->public_pkey_size) {
3898 + fon_critical("%s: plaintext_buffer_size [%u] < %u", __FUNCTION__, plaintext_buffer_size, sign->public_pkey_size);
3899 + return 1;
3900 + }
3901 + if (cryptext_size != sign->public_pkey_size) {
3902 + fon_critical("%s: cryptext_size [%u] != %u", __FUNCTION__, cryptext_size, sign->public_pkey_size);
3903 + return 2;
3904 + }
3905 + retsize = RSA_public_decrypt(cryptext_size, cryptext, plaintext, sign->public_rsa, RSA_NO_PADDING);
3906 + if (retsize == -1)
3907 + return 1;
3908 + *plaintext_size = retsize;
3909 + return 0;
3910 +}
3911 +
3912 +#ifdef __MAINTEST__
3913 +int main(int argc, char **argv)
3914 +{
3915 + size_t argv0_size;
3916 + char *token;
3917 +
3918 + argv0_size = strlen(argv[0]);
3919 + if (argv0_size < 7) {
3920 + fprintf(stderr, "%s?", argv[0]);
3921 + return 1;
3922 + }
3923 + token = argv[0] + argv0_size - 7;
3924 +
3925 + SG_init();
3926 + if (!strcmp(token, "fonsign")) {
3927 + return main_fonsign(argc, argv);
3928 + } else if (!strcmp(token, "foncryp")) {
3929 + return main_foncryp(argc, argv);
3930 + }
3931 + fprintf(stderr, "%s?", argv[0]);
3932 + return 1;
3933 +}
3934 +
3935 +int main_foncryp(int argc, char **argv)
3936 +{
3937 + void *handle = NULL;
3938 + int encrypt = 0;
3939 + char *filebuffer = NULL;
3940 + char crypted[1024];
3941 + int size, crypted_size, ret;
3942 +
3943 + if (argc != 5) {
3944 + printf("Usage: %s encrypt|decrypt <key_file> <file> <crypted_file>\n", argv[0]);
3945 + return 1;
3946 + }
3947 + if (!strcmp(argv[1], "encrypt")) {
3948 + printf("Encryption mode\n");
3949 + encrypt = 1;
3950 + } else
3951 + printf("Decryption mode\n");
3952 + if (encrypt)
3953 + handle = SG_start(argv[2], NULL);
3954 + else
3955 + handle = SG_start(NULL, argv[2]);
3956 + if (handle == NULL) {
3957 + printf("Error loading keys\n");
3958 + return 1;
3959 + }
3960 +
3961 + filebuffer = load_file_in_buffer(argv[3], &size);
3962 + if (filebuffer == NULL) {
3963 + printf("Error reading %s\n", argv[3]);
3964 + SG_stop(handle);
3965 + return 1;
3966 + }
3967 + if (encrypt)
3968 + ret = SG_crypt(handle, filebuffer, size, crypted, 1024, &crypted_size);
3969 + else
3970 + ret = SG_decrypt(handle, filebuffer, size, crypted, 1024, &crypted_size);
3971 +
3972 + if (ret) {
3973 + printf("Error crypting %d bytes\n", size);
3974 + SG_stop(handle);
3975 + return 1;
3976 + }
3977 + printf("Crypted size %d\n", crypted_size);
3978 + if (save_file_from_buffer(argv[4], crypted, crypted_size)) {
3979 + printf("Error saving file\n");
3980 + SG_stop(handle);
3981 + return 1;
3982 + }
3983 +
3984 + SG_stop(handle);
3985 + return 0;
3986 +}
3987 +
3988 +int main_fonsign(int argc, char **argv)
3989 +{
3990 + void *handle = NULL;
3991 + char signature_buffer[4096];
3992 + char *signature;
3993 + unsigned int signature_size;
3994 + struct stat st;
3995 + char *filebuffer = NULL;
3996 + int size;
3997 + int ret = -1;
3998 +
3999 + if (argc != 5) {
4000 + fprintf(stderr, "usage: %s <private_key_file> <public_key_file> <file_to_sign> <signature_file>\n", argv[0]);
4001 + goto end;
4002 + }
4003 + handle = SG_start(argv[1], argv[2]);
4004 + if (handle == NULL) {
4005 + fprintf(stderr, "Error calling SG_start(%s)\n", argv[1]);
4006 + goto end;
4007 + }
4008 + filebuffer = load_file_in_buffer(argv[3], &size);
4009 + if (filebuffer == NULL) {
4010 + fprintf(stderr, "Error reading %s\n", argv[3]);
4011 + goto end;
4012 + }
4013 + if (SG_sign(handle, filebuffer, size, signature_buffer, 4096, &signature_size)) {
4014 + fprintf(stderr, "Error calling SG_sign()\n");
4015 + goto end;
4016 + }
4017 + ret = SG_verify(handle, filebuffer, size, signature_buffer, signature_size);
4018 + if (ret == 0)
4019 + fprintf(stderr, "signature failure\n");
4020 + else if (ret == 1) {
4021 + fprintf(stderr, "signature ok\n");
4022 + ret = 0;
4023 + } else {
4024 + fprintf(stderr, "signature error\n");
4025 + goto end;
4026 + }
4027 + if (save_file_from_buffer(argv[4], signature_buffer, signature_size)) {
4028 + fprintf(stderr, "Error writing to %s\n", argv[4]);
4029 + goto end;
4030 + }
4031 + ret = 0;
4032 +end:
4033 + if (filebuffer != NULL)
4034 + free(filebuffer);
4035 + if (handle != NULL)
4036 + SG_stop(handle);
4037 + return ret;
4038 +}
4039 +#endif
4040 +
4041 --- /dev/null
4042 +++ b/net/uip-0.9/fs.c
4043 @@ -0,0 +1,154 @@
4044 +/**
4045 + * \addtogroup httpd
4046 + * @{
4047 + */
4048 +
4049 +/**
4050 + * \file
4051 + * HTTP server read-only file system code.
4052 + * \author Adam Dunkels <adam@dunkels.com>
4053 + *
4054 + * A simple read-only filesystem.
4055 + */
4056 +
4057 +/*
4058 + * Copyright (c) 2001, Swedish Institute of Computer Science.
4059 + * All rights reserved.
4060 + *
4061 + * Redistribution and use in source and binary forms, with or without
4062 + * modification, are permitted provided that the following conditions
4063 + * are met:
4064 + * 1. Redistributions of source code must retain the above copyright
4065 + * notice, this list of conditions and the following disclaimer.
4066 + * 2. Redistributions in binary form must reproduce the above copyright
4067 + * notice, this list of conditions and the following disclaimer in the
4068 + * documentation and/or other materials provided with the distribution.
4069 + * 3. Neither the name of the Institute nor the names of its contributors
4070 + * may be used to endorse or promote products derived from this software
4071 + * without specific prior written permission.
4072 + *
4073 + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
4074 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4075 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4076 + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
4077 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4078 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4079 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4080 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4081 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4082 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4083 + * SUCH DAMAGE.
4084 + *
4085 + * This file is part of the lwIP TCP/IP stack.
4086 + *
4087 + * Author: Adam Dunkels <adam@sics.se>
4088 + *
4089 + * $Id: fs.c,v 1.7.2.3 2003/10/07 13:22:27 adam Exp $
4090 + */
4091 +
4092 +#include "uip.h"
4093 +#include "httpd.h"
4094 +#include "fs.h"
4095 +#include "fsdata.h"
4096 +
4097 +#include "fsdata.c"
4098 +
4099 +#ifdef FS_STATISTICS
4100 +#if FS_STATISTICS == 1
4101 +static u16_t count[FS_NUMFILES];
4102 +#endif /* FS_STATISTICS */
4103 +#endif /* FS_STATISTICS */
4104 +
4105 +/*-----------------------------------------------------------------------------------*/
4106 +static u8_t
4107 +fs_strcmp(const char *str1, const char *str2)
4108 +{
4109 + u8_t i;
4110 + i = 0;
4111 + loop:
4112 +
4113 + if(str2[i] == 0 ||
4114 + str1[i] == '\r' ||
4115 + str1[i] == '\n') {
4116 + return 0;
4117 + }
4118 +
4119 + if(str1[i] != str2[i]) {
4120 + return 1;
4121 + }
4122 +
4123 +
4124 + ++i;
4125 + goto loop;
4126 +}
4127 +/*-----------------------------------------------------------------------------------*/
4128 +int
4129 +fs_open(const char *name, struct fs_file *file)
4130 +{
4131 +#ifdef FS_STATISTICS
4132 +#if FS_STATISTICS == 1
4133 + u16_t i = 0;
4134 +#endif /* FS_STATISTICS */
4135 +#endif /* FS_STATISTICS */
4136 + struct fsdata_file_noconst *f;
4137 +
4138 + for(f = (struct fsdata_file_noconst *)FS_ROOT;
4139 + f != NULL;
4140 + f = (struct fsdata_file_noconst *)f->next) {
4141 +
4142 + if(fs_strcmp(name, f->name) == 0) {
4143 + file->data = f->data;
4144 + file->len = f->len;
4145 +#ifdef FS_STATISTICS
4146 +#if FS_STATISTICS == 1
4147 + ++count[i];
4148 +#endif /* FS_STATISTICS */
4149 +#endif /* FS_STATISTICS */
4150 + return 1;
4151 + }
4152 +#ifdef FS_STATISTICS
4153 +#if FS_STATISTICS == 1
4154 + ++i;
4155 +#endif /* FS_STATISTICS */
4156 +#endif /* FS_STATISTICS */
4157 +
4158 + }
4159 + return 0;
4160 +}
4161 +/*-----------------------------------------------------------------------------------*/
4162 +void
4163 +fs_init(void)
4164 +{
4165 +#ifdef FS_STATISTICS
4166 +#if FS_STATISTICS == 1
4167 + u16_t i;
4168 + for(i = 0; i < FS_NUMFILES; i++) {
4169 + count[i] = 0;
4170 + }
4171 +#endif /* FS_STATISTICS */
4172 +#endif /* FS_STATISTICS */
4173 +}
4174 +/*-----------------------------------------------------------------------------------*/
4175 +#ifdef FS_STATISTICS
4176 +#if FS_STATISTICS == 1
4177 +u16_t fs_count
4178 +(char *name)
4179 +{
4180 + struct fsdata_file_noconst *f;
4181 + u16_t i;
4182 +
4183 + i = 0;
4184 + for(f = (struct fsdata_file_noconst *)FS_ROOT;
4185 + f != NULL;
4186 + f = (struct fsdata_file_noconst *)f->next) {
4187 +
4188 + if(fs_strcmp(name, f->name) == 0) {
4189 + return count[i];
4190 + }
4191 + ++i;
4192 + }
4193 + return 0;
4194 +}
4195 +#endif /* FS_STATISTICS */
4196 +#endif /* FS_STATISTICS */
4197 +/*-----------------------------------------------------------------------------------*/
4198 --- /dev/null
4199 +++ b/net/uip-0.9/fsdata.c
4200 @@ -0,0 +1,199 @@
4201 +static const char data_flashing_html[] = {
4202 + /* /flashing.html */
4203 + 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4204 + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
4205 + 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
4206 + 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
4207 + 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4208 + 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
4209 + 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
4210 + 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
4211 + 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
4212 + 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
4213 + 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62,
4214 + 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d,
4215 + 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30,
4216 + 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x20, 0x68,
4217 + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25,
4218 + 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23,
4219 + 0x66, 0x66, 0x66, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67,
4220 + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f,
4221 + 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 0x62, 0x30, 0x33, 0x34,
4222 + 0x3b, 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72,
4223 + 0x3e, 0x3c, 0x68, 0x31, 0x3e, 0x55, 0x70, 0x67, 0x72, 0x61,
4224 + 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
4225 + 0x6d, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x68, 0x31,
4226 + 0x3e, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
4227 + 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68,
4228 + 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
4229 +
4230 +static const char data_fail_html[] = {
4231 + /* /fail.html */
4232 + 0x2f, 0x66, 0x61, 0x69, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4233 + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
4234 + 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
4235 + 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
4236 + 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4237 + 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
4238 + 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
4239 + 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
4240 + 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
4241 + 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
4242 + 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
4243 + 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
4244 + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
4245 + 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
4246 + 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
4247 + 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
4248 + 0x3e, 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
4249 + 0x9, 0x9, 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73,
4250 + 0x68, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65,
4251 + 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 0x45,
4252 + 0x52, 0x52, 0x4f, 0x52, 0x20, 0x2d, 0x20, 0x74, 0x68, 0x65,
4253 + 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x79, 0x6f, 0x75,
4254 + 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20,
4255 + 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
4256 + 0x70, 0x61, 0x73, 0x73, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66,
4257 + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x50,
4258 + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65,
4259 + 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75,
4260 + 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x69,
4261 + 0x63, 0x69, 0x61, 0x6c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74,
4262 + 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64,
4263 + 0x20, 0x62, 0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4264 + 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e,
4265 + 0x66, 0x6f, 0x6e, 0x6f, 0x73, 0x66, 0x65, 0x72, 0x61, 0x2e,
4266 + 0x6f, 0x72, 0x67, 0x2f, 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f,
4267 + 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
4268 + 0x3e, 0xa, };
4269 +
4270 +static const char data_404_html[] = {
4271 + /* /404.html */
4272 + 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4273 + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34,
4274 + 0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f,
4275 + 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53,
4276 + 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50,
4277 + 0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70,
4278 + 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73,
4279 + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f,
4280 + 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e,
4281 + 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a,
4282 + 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
4283 + 0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e,
4284 + 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f,
4285 + 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65,
4286 + 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
4287 + 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20,
4288 + 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66,
4289 + 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c,
4290 + 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f,
4291 + 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d,
4292 + 0x6c, 0x3e, };
4293 +
4294 +static const char data_index_html[] = {
4295 + /* /index.html */
4296 + 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4297 + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
4298 + 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
4299 + 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
4300 + 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4301 + 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
4302 + 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
4303 + 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
4304 + 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
4305 + 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
4306 + 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
4307 + 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
4308 + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
4309 + 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
4310 + 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
4311 + 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
4312 + 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
4313 + 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
4314 + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
4315 + 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
4316 + 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
4317 + 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
4318 + 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
4319 + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
4320 + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
4321 + 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
4322 + 0x3c, 0x68, 0x31, 0x3e, 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65,
4323 + 0x72, 0x61, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66,
4324 + 0x65, 0x20, 0x55, 0x49, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa,
4325 + 0x9, 0x9, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65,
4326 + 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74,
4327 + 0x22, 0x20, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3d,
4328 + 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74,
4329 + 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61,
4330 + 0x22, 0x3e, 0xa, 0x9, 0x9, 0x9, 0x3c, 0x69, 0x6e, 0x70,
4331 + 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x69,
4332 + 0x6c, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x69,
4333 + 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x3e, 0xa, 0x9, 0x9,
4334 + 0x9, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79,
4335 + 0x70, 0x65, 0x3d, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3e,
4336 + 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e,
4337 + 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
4338 + 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
4339 +
4340 +static const char data_flash_html[] = {
4341 + /* /flash.html */
4342 + 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4343 + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
4344 + 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
4345 + 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
4346 + 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4347 + 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
4348 + 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
4349 + 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
4350 + 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
4351 + 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
4352 + 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
4353 + 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
4354 + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
4355 + 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
4356 + 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
4357 + 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
4358 + 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
4359 + 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
4360 + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
4361 + 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
4362 + 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
4363 + 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
4364 + 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
4365 + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
4366 + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
4367 + 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
4368 + 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x69,
4369 + 0x6e, 0x67, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9,
4370 + 0x54, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
4371 + 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x72,
4372 + 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c,
4373 + 0x61, 0x73, 0x68, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68,
4374 + 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70,
4375 + 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x74, 0x68,
4376 + 0x65, 0x20, 0x6c, 0x65, 0x64, 0x73, 0x20, 0x77, 0x69, 0x6c,
4377 + 0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x6f,
4378 + 0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0xa, 0xa, 0x9,
4379 + 0x9, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x73,
4380 + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6c,
4381 + 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68,
4382 + 0x65, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x77, 0x69, 0x6c, 0x6c,
4383 + 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0xa, 0x9, 0x3c,
4384 + 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68,
4385 + 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
4386 +
4387 +const struct fsdata_file file_flashing_html[] = {{NULL, data_flashing_html, data_flashing_html + 15, sizeof(data_flashing_html) - 15}};
4388 +
4389 +const struct fsdata_file file_fail_html[] = {{file_flashing_html, data_fail_html, data_fail_html + 11, sizeof(data_fail_html) - 11}};
4390 +
4391 +const struct fsdata_file file_404_html[] = {{file_fail_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
4392 +
4393 +const struct fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
4394 +
4395 +const struct fsdata_file file_flash_html[] = {{file_index_html, data_flash_html, data_flash_html + 12, sizeof(data_flash_html) - 12}};
4396 +
4397 +#define FS_ROOT file_flash_html
4398 +
4399 +#define FS_NUMFILES 5
4400 \ No newline at end of file
4401 --- /dev/null
4402 +++ b/net/uip-0.9/fsdata.h
4403 @@ -0,0 +1,64 @@
4404 +/*
4405 + * Copyright (c) 2001, Swedish Institute of Computer Science.
4406 + * All rights reserved.
4407 + *
4408 + * Redistribution and use in source and binary forms, with or without
4409 + * modification, are permitted provided that the following conditions
4410 + * are met:
4411 + * 1. Redistributions of source code must retain the above copyright
4412 + * notice, this list of conditions and the following disclaimer.
4413 + * 2. Redistributions in binary form must reproduce the above copyright
4414 + * notice, this list of conditions and the following disclaimer in the
4415 + * documentation and/or other materials provided with the distribution.
4416 + * 3. Neither the name of the Institute nor the names of its contributors
4417 + * may be used to endorse or promote products derived from this software
4418 + * without specific prior written permission.
4419 + *
4420 + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
4421 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4422 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4423 + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
4424 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4425 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4426 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4427 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4428 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4429 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4430 + * SUCH DAMAGE.
4431 + *
4432 + * This file is part of the lwIP TCP/IP stack.
4433 + *
4434 + * Author: Adam Dunkels <adam@sics.se>
4435 + *
4436 + * $Id: fsdata.h,v 1.4.2.1 2003/10/04 22:54:06 adam Exp $
4437 + */
4438 +#ifndef __FSDATA_H__
4439 +#define __FSDATA_H__
4440 +
4441 +#include "uipopt.h"
4442 +
4443 +struct fsdata_file {
4444 + const struct fsdata_file *next;
4445 + const char *name;
4446 + const char *data;
4447 + const int len;
4448 +#ifdef FS_STATISTICS
4449 +#if FS_STATISTICS == 1
4450 + u16_t count;
4451 +#endif /* FS_STATISTICS */
4452 +#endif /* FS_STATISTICS */
4453 +};
4454 +
4455 +struct fsdata_file_noconst {
4456 + struct fsdata_file *next;
4457 + char *name;
4458 + char *data;
4459 + int len;
4460 +#ifdef FS_STATISTICS
4461 +#if FS_STATISTICS == 1
4462 + u16_t count;
4463 +#endif /* FS_STATISTICS */
4464 +#endif /* FS_STATISTICS */
4465 +};
4466 +
4467 +#endif /* __FSDATA_H__ */
4468 --- /dev/null
4469 +++ b/net/uip-0.9/fs.h
4470 @@ -0,0 +1,80 @@
4471 +/**
4472 + * \addtogroup httpd
4473 + * @{
4474 + */
4475 +
4476 +/**
4477 + * \file
4478 + * HTTP server read-only file system header file.
4479 + * \author Adam Dunkels <adam@dunkels.com>
4480 + */
4481 +
4482 +/*
4483 + * Copyright (c) 2001, Swedish Institute of Computer Science.
4484 + * All rights reserved.
4485 + *
4486 + * Redistribution and use in source and binary forms, with or without
4487 + * modification, are permitted provided that the following conditions
4488 + * are met:
4489 + * 1. Redistributions of source code must retain the above copyright
4490 + * notice, this list of conditions and the following disclaimer.
4491 + * 2. Redistributions in binary form must reproduce the above copyright
4492 + * notice, this list of conditions and the following disclaimer in the
4493 + * documentation and/or other materials provided with the distribution.
4494 + * 3. Neither the name of the Institute nor the names of its contributors
4495 + * may be used to endorse or promote products derived from this software
4496 + * without specific prior written permission.
4497 + *
4498 + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
4499 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4500 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4501 + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
4502 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4503 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4504 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4505 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4506 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4507 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4508 + * SUCH DAMAGE.
4509 + *
4510 + * This file is part of the lwIP TCP/IP stack.
4511 + *
4512 + * Author: Adam Dunkels <adam@sics.se>
4513 + *
4514 + * $Id: fs.h,v 1.6.2.3 2003/10/07 13:22:27 adam Exp $
4515 + */
4516 +#ifndef __FS_H__
4517 +#define __FS_H__
4518 +
4519 +#include "uip.h"
4520 +
4521 +/**
4522 + * An open file in the read-only file system.
4523 + */
4524 +struct fs_file {
4525 + char *data; /**< The actual file data. */
4526 + int len; /**< The length of the file data. */
4527 +};
4528 +
4529 +/**
4530 + * Open a file in the read-only file system.
4531 + *
4532 + * \param name The name of the file.
4533 + *
4534 + * \param file The file pointer, which must be allocated by caller and
4535 + * will be filled in by the function.
4536 + */
4537 +int fs_open(const char *name, struct fs_file *file);
4538 +
4539 +#ifdef FS_STATISTICS
4540 +#if FS_STATISTICS == 1
4541 +u16_t fs_count(char *name);
4542 +#endif /* FS_STATISTICS */
4543 +#endif /* FS_STATISTICS */
4544 +
4545 +/**
4546 + * Initialize the read-only file system.
4547 + */
4548 +void fs_init(void);
4549 +
4550 +#endif /* __FS_H__ */
4551 --- /dev/null
4552 +++ b/net/uip-0.9/httpd.c
4553 @@ -0,0 +1,278 @@
4554 +#include "uip.h"
4555 +#include "httpd.h"
4556 +#include "fs.h"
4557 +#include "fsdata.h"
4558 +#include <asm/addrspace.h>
4559 +
4560 +#define HTTP_NONE 0
4561 +#define HTTP_FILE 1
4562 +#define HTTP_FIRMWARE 2
4563 +
4564 +#define PRINT(x) printf("%s", x)
4565 +#define PRINTLN(x) printf("%s\n", x)
4566 +
4567 +extern unsigned long do_http_tmp_address(void);
4568 +
4569 +struct httpd_state *hs;
4570 +
4571 +extern const struct fsdata_file file_index_html;
4572 +extern const struct fsdata_file file_404_html;
4573 +extern const struct fsdata_file file_flash_html;
4574 +extern int httpd_upload_complete;
4575 +extern unsigned char *httpd_upload_data;
4576 +unsigned char *upload_data;
4577 +extern ulong NetBootFileXferSize;
4578 +int upload_running = 0;
4579 +
4580 +#define ISO_G 0x47
4581 +#define ISO_E 0x45
4582 +#define ISO_T 0x54
4583 +#define ISO_P 0x50
4584 +#define ISO_O 0x4f
4585 +#define ISO_S 0x53
4586 +#define ISO_T 0x54
4587 +#define ISO_slash 0x2f
4588 +#define ISO_c 0x63
4589 +#define ISO_g 0x67
4590 +#define ISO_i 0x69
4591 +#define ISO_space 0x20
4592 +#define ISO_nl 0x0a
4593 +#define ISO_cr 0x0d
4594 +#define ISO_a 0x61
4595 +#define ISO_t 0x74
4596 +#define ISO_hash 0x23
4597 +#define ISO_period 0x2e
4598 +
4599 +static char eol[3] = { 0x0d, 0x0a, 0x00 };
4600 +static char eol2[5] = { 0x0d, 0x0a, 0x0d, 0x0a, 0x00 };
4601 +static char boundary[128];
4602 +static int boundary_len = 0;
4603 +
4604 +/* we use this so that we can do without the ctype library */
4605 +#define is_digit(c) ((c) >= '0' && (c) <= '9')
4606 +static int atoi(const char *s)
4607 +{
4608 + int i=0;
4609 +
4610 + while (is_digit(*s))
4611 + i = i*10 + *(s++) - '0';
4612 + return i;
4613 +}
4614 +
4615 +void
4616 +httpd_init(void)
4617 +{
4618 + fs_init();
4619 + uip_listen(HTONS(80));
4620 +}
4621 +
4622 +void
4623 +httpd_appcall(void)
4624 +{
4625 + struct fs_file fsfile;
4626 + u8_t i;
4627 + switch(uip_conn->lport) {
4628 + case HTONS(80):
4629 + hs = (struct httpd_state *)(uip_conn->appstate);
4630 + if(uip_connected())
4631 + {
4632 + hs->state = HTTP_NONE;
4633 + hs->count = 0;
4634 + return;
4635 + } else if(uip_poll())
4636 + {
4637 + if(hs->count++ >= 1000) {
4638 + uip_abort();
4639 + }
4640 + return;
4641 + } else if(uip_newdata() && hs->state == HTTP_NONE)
4642 + {
4643 + if(uip_appdata[0] == ISO_G &&
4644 + uip_appdata[1] == ISO_E &&
4645 + uip_appdata[2] == ISO_T &&
4646 + uip_appdata[3] == ISO_space)
4647 + {
4648 + hs->state = HTTP_FILE;
4649 + }
4650 + if(uip_appdata[0] == ISO_P &&
4651 + uip_appdata[1] == ISO_O &&
4652 + uip_appdata[2] == ISO_S &&
4653 + uip_appdata[3] == ISO_T &&
4654 + uip_appdata[4] == ISO_space)
4655 + {
4656 + hs->state = HTTP_FIRMWARE;
4657 + }
4658 + if(hs->state == HTTP_NONE)
4659 + {
4660 + uip_abort();
4661 + return;
4662 + }
4663 + if(hs->state == HTTP_FILE)
4664 + {
4665 + for(i = 4; i < 40; ++i)
4666 + {
4667 + if(uip_appdata[i] == ISO_space ||
4668 + uip_appdata[i] == ISO_cr ||
4669 + uip_appdata[i] == ISO_nl)
4670 + {
4671 + uip_appdata[i] = 0;
4672 + break;
4673 + }
4674 + }
4675 +
4676 + PRINT("request for file ");
4677 + PRINTLN(&uip_appdata[4]);
4678 + if(uip_appdata[4] == ISO_slash &&
4679 + uip_appdata[5] == 0)
4680 + {
4681 + fs_open(file_index_html.name, &fsfile);
4682 + } else {
4683 + if(!fs_open((const char *)&uip_appdata[4], &fsfile))
4684 + {
4685 + PRINTLN("couldn't open file");
4686 + fs_open(file_index_html.name, &fsfile);
4687 + }
4688 + }
4689 + hs->script = 0;
4690 + hs->state = HTTP_FILE;
4691 + hs->dataptr = fsfile.data;
4692 + hs->count = fsfile.len;
4693 + }
4694 + if(hs->state == HTTP_FIRMWARE)
4695 + {
4696 + unsigned char *start = (unsigned char*)uip_appdata;
4697 + char *clen = strstr(start, "Content-Length:");
4698 + int len = 0;
4699 + unsigned char *next, *end;
4700 + unsigned char *boundary_start;
4701 + int i;
4702 + uip_appdata[uip_len] = '\0';
4703 + if(clen)
4704 + {
4705 + clen += sizeof("Content-Length:");
4706 + next = strstr(clen, eol);
4707 + if(next)
4708 + {
4709 + len = atoi(clen);
4710 + next++;
4711 + printf("expecting %d bytes\n", len);
4712 + upload_data = httpd_upload_data = (unsigned char *)do_http_tmp_address();
4713 + printf("received data will be stored at 0x%08X\n", upload_data);
4714 + if(!upload_data)
4715 + {
4716 + printf("failed to allocate memory\n");
4717 + uip_close();
4718 + return;
4719 + }
4720 + } else {
4721 + uip_close();
4722 + return;
4723 + }
4724 + }
4725 + if(len < 4 * 1024)
4726 + {
4727 + uip_close();
4728 + return;
4729 + }
4730 + boundary_start = strstr(next, "---");
4731 + if(!boundary_start)
4732 + {
4733 + uip_close();
4734 + return;
4735 + }
4736 + end = strstr(boundary_start, eol);
4737 + if(!eol)
4738 + {
4739 + uip_close();
4740 + return;
4741 + }
4742 + boundary_len = end - boundary_start;
4743 + memcpy(boundary, boundary_start, boundary_len);
4744 + boundary[boundary_len] = 0;
4745 + next = strstr(boundary_start, "name=\"firmware\";");
4746 + if(!next)
4747 + {
4748 + uip_close();
4749 + return;
4750 + }
4751 + next = strstr(next, eol2);
4752 + if(!next)
4753 + {
4754 + printf("could not find start of data\n");
4755 + uip_close();
4756 + return;
4757 + }
4758 + next += 4;
4759 + hs->script = 0;
4760 + hs->state = HTTP_FIRMWARE;
4761 + hs->upload = uip_len - (next - start);
4762 + hs->upload_total = len - (int)(next - boundary_start);
4763 + hs->upload_total -= (strlen(boundary) + 6);
4764 + //printf("storing %d bytes at %p\n", (int)hs->upload, upload_data);
4765 + for(i = 0; i < hs->upload; i++)
4766 + upload_data[i] = next[i];
4767 + upload_data += (int)hs->upload;
4768 + printf("%d / %d\n", (int)hs->upload, hs->upload_total);
4769 + uip_slen = 0;
4770 + return;
4771 + }
4772 + }
4773 +
4774 + if(hs->state == HTTP_FIRMWARE)
4775 + {
4776 + if(uip_newdata())
4777 + {
4778 + int i;
4779 + hs->count = 0;
4780 + uip_appdata[uip_len] = '\0';
4781 + hs->upload += uip_len;
4782 + //printf("storing %d bytes at %p\n", uip_len, upload_data);
4783 + printf("%d / %d\n", (int)hs->upload, hs->upload_total);
4784 + for(i = 0; i < uip_len; i++)
4785 + upload_data[i] = uip_appdata[i];
4786 + upload_data += uip_len;
4787 + uip_slen = 0;
4788 + if(hs->upload >= hs->upload_total)
4789 + {
4790 + upload_running = 1;
4791 + NetBootFileXferSize = hs->upload_total;
4792 + fs_open(file_flash_html.name, &fsfile);
4793 + hs->script = 0;
4794 + hs->state = HTTP_FILE;
4795 + hs->dataptr = fsfile.data;
4796 + hs->count = fsfile.len;
4797 + }
4798 + }
4799 + }
4800 + if(hs->state == HTTP_FILE)
4801 + {
4802 + if(uip_acked())
4803 + {
4804 + if(hs->count >= uip_conn->len)
4805 + {
4806 + hs->count -= uip_conn->len;
4807 + hs->dataptr += uip_conn->len;
4808 + } else {
4809 + hs->count = 0;
4810 + }
4811 + if(hs->count == 0)
4812 + {
4813 + if(upload_running)
4814 + {
4815 + int i;
4816 + httpd_upload_complete = 1;
4817 + // for(i = 0; i < hs->upload_total; i++)
4818 + // printf("%c", httpd_upload_data[i]);
4819 + }
4820 + uip_close();
4821 + }
4822 + }
4823 + uip_send(hs->dataptr, hs->count);
4824 + }
4825 + break;
4826 +
4827 + default:
4828 + uip_abort();
4829 + break;
4830 + }
4831 +}
4832 --- /dev/null
4833 +++ b/net/uip-0.9/httpd.h
4834 @@ -0,0 +1,83 @@
4835 +/**
4836 + * \addtogroup httpd
4837 + * @{
4838 + */
4839 +
4840 +/**
4841 + * \file
4842 + * HTTP server header file.
4843 + * \author Adam Dunkels <adam@dunkels.com>
4844 + */
4845 +
4846 +/*
4847 + * Copyright (c) 2001, Adam Dunkels.
4848 + * All rights reserved.
4849 + *
4850 + * Redistribution and use in source and binary forms, with or without
4851 + * modification, are permitted provided that the following conditions
4852 + * are met:
4853 + * 1. Redistributions of source code must retain the above copyright
4854 + * notice, this list of conditions and the following disclaimer.
4855 + * 2. Redistributions in binary form must reproduce the above copyright
4856 + * notice, this list of conditions and the following disclaimer in the
4857 + * documentation and/or other materials provided with the distribution.
4858 + * 3. The name of the author may not be used to endorse or promote
4859 + * products derived from this software without specific prior
4860 + * written permission.
4861 + *
4862 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4863 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4864 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4865 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4866 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4867 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4868 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4869 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4870 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4871 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4872 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4873 + *
4874 + * This file is part of the uIP TCP/IP stack.
4875 + *
4876 + * $Id: httpd.h,v 1.4.2.3 2003/10/06 22:56:44 adam Exp $
4877 + *
4878 + */
4879 +
4880 +#ifndef __HTTPD_H__
4881 +#define __HTTPD_H__
4882 +
4883 +void httpd_init(void);
4884 +void httpd_appcall(void);
4885 +
4886 +/* UIP_APPCALL: the name of the application function. This function
4887 + must return void and take no arguments (i.e., C type "void
4888 + appfunc(void)"). */
4889 +#ifndef UIP_APPCALL
4890 +#define UIP_APPCALL httpd_appcall
4891 +#endif
4892 +
4893 +struct httpd_state {
4894 + u8_t state;
4895 + u16_t count;
4896 + char *dataptr;
4897 + char *script;
4898 + unsigned int upload;
4899 + unsigned int upload_total;
4900 +};
4901 +
4902 +
4903 +/* UIP_APPSTATE_SIZE: The size of the application-specific state
4904 + stored in the uip_conn structure. */
4905 +#ifndef UIP_APPSTATE_SIZE
4906 +#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
4907 +#endif
4908 +
4909 +#define FS_STATISTICS 1
4910 +
4911 +extern struct httpd_state *hs;
4912 +
4913 +
4914 +/* we copy the data to RAM+10MB */
4915 +#define TMP_DATA 0x8A100000
4916 +
4917 +#endif /* __HTTPD_H__ */
4918 --- /dev/null
4919 +++ b/net/uip-0.9/main.c
4920 @@ -0,0 +1,88 @@
4921 +/*
4922 + * Copyright (c) 2001-2003, Adam Dunkels.
4923 + * All rights reserved.
4924 + *
4925 + * Redistribution and use in source and binary forms, with or without
4926 + * modification, are permitted provided that the following conditions
4927 + * are met:
4928 + * 1. Redistributions of source code must retain the above copyright
4929 + * notice, this list of conditions and the following disclaimer.
4930 + * 2. Redistributions in binary form must reproduce the above copyright
4931 + * notice, this list of conditions and the following disclaimer in the
4932 + * documentation and/or other materials provided with the distribution.
4933 + * 3. The name of the author may not be used to endorse or promote
4934 + * products derived from this software without specific prior
4935 + * written permission.
4936 + *
4937 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4938 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4939 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4940 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4941 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4942 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4943 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4944 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4945 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4946 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4947 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4948 + *
4949 + * This file is part of the uIP TCP/IP stack.
4950 + *
4951 + * $Id: main.c,v 1.10.2.1 2003/10/04 22:54:17 adam Exp $
4952 + *
4953 + */
4954 +
4955 +
4956 +#include "uip.h"
4957 +#include "uip_arp.h"
4958 +#include "tapdev.h"
4959 +#include "httpd.h"
4960 +
4961 +#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
4962 +
4963 +#ifndef NULL
4964 +#define NULL (void *)0
4965 +#endif /* NULL */
4966 +
4967 +/*-----------------------------------------------------------------------------------*/
4968 +int
4969 +main(void)
4970 +{
4971 + u8_t i, arptimer;
4972 + tapdev_init();
4973 + uip_init();
4974 + httpd_init();
4975 + arptimer = 0;
4976 + while(1) {
4977 + uip_len = tapdev_read();
4978 + if(uip_len == 0) {
4979 + for(i = 0; i < UIP_CONNS; i++) {
4980 + uip_periodic(i);
4981 + if(uip_len > 0) {
4982 + uip_arp_out();
4983 + tapdev_send();
4984 + }
4985 + }
4986 +
4987 + if(++arptimer == 20) {
4988 + uip_arp_timer();
4989 + arptimer = 0;
4990 + }
4991 + } else {
4992 + if(BUF->type == htons(UIP_ETHTYPE_IP)) {
4993 + uip_arp_ipin();
4994 + uip_input();
4995 + if(uip_len > 0) {
4996 + uip_arp_out();
4997 + tapdev_send();
4998 + }
4999 + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
5000 + uip_arp_arpin();
5001 + if(uip_len > 0) {
5002 + tapdev_send();
5003 + }
5004 + }
5005 + }
5006 + }
5007 + return 0;
5008 +}
5009 --- /dev/null
5010 +++ b/net/uip-0.9/Makefile
5011 @@ -0,0 +1,54 @@
5012 +# Copyright (c) 2001, Adam Dunkels.
5013 +# All rights reserved.
5014 +#
5015 +# Redistribution and use in source and binary forms, with or without
5016 +# modification, are permitted provided that the following conditions
5017 +# are met:
5018 +# 1. Redistributions of source code must retain the above copyright
5019 +# notice, this list of conditions and the following disclaimer.
5020 +# 2. Redistributions in binary form must reproduce the above copyright
5021 +# notice, this list of conditions and the following disclaimer in the
5022 +# documentation and/or other materials provided with the distribution.
5023 +# 3. All advertising materials mentioning features or use of this software
5024 +# must display the following acknowledgement:
5025 +# This product includes software developed by Adam Dunkels.
5026 +# 4. The name of the author may not be used to endorse or promote
5027 +# products derived from this software without specific prior
5028 +# written permission.
5029 +#
5030 +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5031 +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5032 +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5033 +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5034 +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5035 +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5036 +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5037 +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5038 +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5039 +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5040 +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5041 +#
5042 +# This file is part of the uIP TCP/IP stack.
5043 +#
5044 +# $Id: Makefile,v 1.8.2.2 2003/10/04 22:54:17 adam Exp $
5045 +#
5046 +
5047 +CC=gcc
5048 +CFLAGS=-Wall -fpack-struct -DDUMP=0
5049 +
5050 +all: uip
5051 +
5052 +uip: uip.o uip_arch.o tapdev.o httpd.o main.o fs.o uip_arp.o
5053 + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
5054 +
5055 +%.o: %.c
5056 + $(CC) $(CFLAGS) -c $^ -o $@
5057 +
5058 +clean:
5059 + rm -f *.o *~ *core uip
5060 +
5061 +
5062 +
5063 +
5064 +
5065 +
5066 --- /dev/null
5067 +++ b/net/uip-0.9/tapdev.c
5068 @@ -0,0 +1,192 @@
5069 +/*
5070 + * Copyright (c) 2001, Swedish Institute of Computer Science.
5071 + * All rights reserved.
5072 + *
5073 + * Redistribution and use in source and binary forms, with or without
5074 + * modification, are permitted provided that the following conditions
5075 + * are met:
5076 + *
5077 + * 1. Redistributions of source code must retain the above copyright
5078 + * notice, this list of conditions and the following disclaimer.
5079 + *
5080 + * 2. Redistributions in binary form must reproduce the above copyright
5081 + * notice, this list of conditions and the following disclaimer in the
5082 + * documentation and/or other materials provided with the distribution.
5083 + *
5084 + * 3. Neither the name of the Institute nor the names of its contributors
5085 + * may be used to endorse or promote products derived from this software
5086 + * without specific prior written permission.
5087 + *
5088 + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
5089 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5090 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5091 + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
5092 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5093 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5094 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5095 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5096 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5097 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5098 + * SUCH DAMAGE.
5099 + *
5100 + * Author: Adam Dunkels <adam@sics.se>
5101 + *
5102 + * $Id: tapdev.c,v 1.7.2.1 2003/10/07 13:23:19 adam Exp $
5103 + */
5104 +
5105 +
5106 +#include <fcntl.h>
5107 +#include <stdlib.h>
5108 +#include <stdio.h>
5109 +#include <unistd.h>
5110 +#include <string.h>
5111 +#include <sys/ioctl.h>
5112 +#include <sys/socket.h>
5113 +#include <sys/types.h>
5114 +#include <sys/time.h>
5115 +#include <sys/uio.h>
5116 +#include <sys/socket.h>
5117 +
5118 +#ifdef linux
5119 +#include <sys/ioctl.h>
5120 +#include <linux/if.h>
5121 +#include <linux/if_tun.h>
5122 +#define DEVTAP "/dev/net/tun"
5123 +#else /* linux */
5124 +#define DEVTAP "/dev/tap0"
5125 +#endif /* linux */
5126 +
5127 +#include "uip.h"
5128 +
5129 +static int fd;
5130 +
5131 +static unsigned long lasttime;
5132 +static struct timezone tz;
5133 +
5134 +/*-----------------------------------------------------------------------------------*/
5135 +void
5136 +tapdev_init(void)
5137 +{
5138 + char buf[1024];
5139 +
5140 + fd = open(DEVTAP, O_RDWR);
5141 + if(fd == -1) {
5142 + perror("tapdev: tapdev_init: open");
5143 + exit(1);
5144 + }
5145 +
5146 +#ifdef linux
5147 + {
5148 + struct ifreq ifr;
5149 + memset(&ifr, 0, sizeof(ifr));
5150 + ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
5151 + if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
5152 + perror(buf);
5153 + exit(1);
5154 + }
5155 + }
5156 +#endif /* Linux */
5157 +
5158 + snprintf(buf, sizeof(buf), "ifconfig tap0 inet %d.%d.%d.%d",
5159 + UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3);
5160 + system(buf);
5161 +
5162 + lasttime = 0;
5163 +}
5164 +
5165 +void dump_mem(int type, int len)
5166 +{
5167 +#if DUMP == 1
5168 + int i;
5169 + for(i = 0; i < len; i++)
5170 + printf("%c", uip_buf[i]);
5171 + if(type)
5172 + {
5173 + printf("\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01");
5174 + printf("\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01");
5175 + } else {
5176 + printf("\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02");
5177 + printf("\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02");
5178 + }
5179 + fflush(stdout);
5180 +#endif
5181 +}
5182 +
5183 +/*-----------------------------------------------------------------------------------*/
5184 +unsigned int
5185 +tapdev_read(void)
5186 +{
5187 + fd_set fdset;
5188 + struct timeval tv, now;
5189 + int ret;
5190 +
5191 + if(lasttime >= 500000) {
5192 + lasttime = 0;
5193 + return 0;
5194 + }
5195 +
5196 + tv.tv_sec = 0;
5197 + tv.tv_usec = 500000 - lasttime;
5198 +
5199 +
5200 + FD_ZERO(&fdset);
5201 + FD_SET(fd, &fdset);
5202 +
5203 + gettimeofday(&now, &tz);
5204 + ret = select(fd + 1, &fdset, NULL, NULL, &tv);
5205 + if(ret == 0) {
5206 + lasttime = 0;
5207 + return 0;
5208 + }
5209 + ret = read(fd, uip_buf, UIP_BUFSIZE);
5210 + if(ret == -1) {
5211 + perror("tap_dev: tapdev_read: read");
5212 + }
5213 + gettimeofday(&tv, &tz);
5214 + lasttime += (tv.tv_sec - now.tv_sec) * 1000000 + (tv.tv_usec - now.tv_usec);
5215 + dump_mem(0, ret);
5216 + return ret;
5217 +}
5218 +/*-----------------------------------------------------------------------------------*/
5219 +void
5220 +tapdev_send(void)
5221 +{
5222 + int ret;
5223 + struct iovec iov[2];
5224 +
5225 +#ifdef linux
5226 + {
5227 + char tmpbuf[UIP_BUFSIZE];
5228 + int i;
5229 +
5230 + for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
5231 + tmpbuf[i] = uip_buf[i];
5232 + }
5233 +
5234 + for(; i < uip_len; i++) {
5235 + tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
5236 + }
5237 +
5238 + ret = write(fd, tmpbuf, uip_len);
5239 + }
5240 +#else
5241 +
5242 + if(uip_len < 40 + UIP_LLH_LEN) {
5243 + ret = write(fd, uip_buf, uip_len + UIP_LLH_LEN);
5244 + } else {
5245 + iov[0].iov_base = uip_buf;
5246 + iov[0].iov_len = 40 + UIP_LLH_LEN;
5247 + iov[1].iov_base = (char *)uip_appdata;
5248 + iov[1].iov_len = uip_len - (40 + UIP_LLH_LEN);
5249 +
5250 + ret = writev(fd, iov, 2);
5251 + }
5252 +#endif
5253 + dump_mem(1, ret);
5254 +
5255 + if(ret == -1) {
5256 + perror("tap_dev: tapdev_send: writev");
5257 + exit(1);
5258 + }
5259 +}
5260 +/*-----------------------------------------------------------------------------------*/
5261 --- /dev/null
5262 +++ b/net/uip-0.9/tapdev.h
5263 @@ -0,0 +1,42 @@
5264 +/*
5265 + * Copyright (c) 2001, Adam Dunkels.
5266 + * All rights reserved.
5267 + *
5268 + * Redistribution and use in source and binary forms, with or without
5269 + * modification, are permitted provided that the following conditions
5270 + * are met:
5271 + * 1. Redistributions of source code must retain the above copyright
5272 + * notice, this list of conditions and the following disclaimer.
5273 + * 2. Redistributions in binary form must reproduce the above copyright
5274 + * notice, this list of conditions and the following disclaimer in the
5275 + * documentation and/or other materials provided with the distribution.
5276 + * 3. The name of the author may not be used to endorse or promote
5277 + * products derived from this software without specific prior
5278 + * written permission.
5279 + *
5280 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5281 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5282 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5283 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5284 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5285 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5286 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5287 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5288 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5289 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5290 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5291 + *
5292 + * This file is part of the uIP TCP/IP stack.
5293 + *
5294 + * $Id: tapdev.h,v 1.1.2.1 2003/10/04 22:54:17 adam Exp $
5295 + *
5296 + */
5297 +
5298 +#ifndef __TAPDEV_H__
5299 +#define __TAPDEV_H__
5300 +
5301 +void tapdev_init(void);
5302 +unsigned int tapdev_read(void);
5303 +void tapdev_send(void);
5304 +
5305 +#endif /* __TAPDEV_H__ */
5306 --- /dev/null
5307 +++ b/net/uip-0.9/uip_arch.c
5308 @@ -0,0 +1,145 @@
5309 +/*
5310 + * Copyright (c) 2001, Adam Dunkels.
5311 + * All rights reserved.
5312 + *
5313 + * Redistribution and use in source and binary forms, with or without
5314 + * modification, are permitted provided that the following conditions
5315 + * are met:
5316 + * 1. Redistributions of source code must retain the above copyright
5317 + * notice, this list of conditions and the following disclaimer.
5318 + * 2. Redistributions in binary form must reproduce the above copyright
5319 + * notice, this list of conditions and the following disclaimer in the
5320 + * documentation and/or other materials provided with the distribution.
5321 + * 3. The name of the author may not be used to endorse or promote
5322 + * products derived from this software without specific prior
5323 + * written permission.
5324 + *
5325 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5326 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5327 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5328 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5329 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5330 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5331 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5332 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5333 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5334 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5335 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5336 + *
5337 + * This file is part of the uIP TCP/IP stack.
5338 + *
5339 + * $Id: uip_arch.c,v 1.2.2.1 2003/10/04 22:54:17 adam Exp $
5340 + *
5341 + */
5342 +
5343 +
5344 +#include "uip.h"
5345 +#include "uip_arch.h"
5346 +
5347 +#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
5348 +#define IP_PROTO_TCP 6
5349 +
5350 +/*-----------------------------------------------------------------------------------*/
5351 +void
5352 +uip_add32(u8_t *op32, u16_t op16)
5353 +{
5354 +
5355 + uip_acc32[3] = op32[3] + (op16 & 0xff);
5356 + uip_acc32[2] = op32[2] + (op16 >> 8);
5357 + uip_acc32[1] = op32[1];
5358 + uip_acc32[0] = op32[0];
5359 +
5360 + if(uip_acc32[2] < (op16 >> 8)) {
5361 + ++uip_acc32[1];
5362 + if(uip_acc32[1] == 0) {
5363 + ++uip_acc32[0];
5364 + }
5365 + }
5366 +
5367 +
5368 + if(uip_acc32[3] < (op16 & 0xff)) {
5369 + ++uip_acc32[2];
5370 + if(uip_acc32[2] == 0) {
5371 + ++uip_acc32[1];
5372 + if(uip_acc32[1] == 0) {
5373 + ++uip_acc32[0];
5374 + }
5375 + }
5376 + }
5377 +}
5378 +/*-----------------------------------------------------------------------------------*/
5379 +u16_t
5380 +uip_chksum(u16_t *sdata, u16_t len)
5381 +{
5382 + u16_t acc;
5383 +
5384 + for(acc = 0; len > 1; len -= 2) {
5385 + acc += *sdata;
5386 + if(acc < *sdata) {
5387 + /* Overflow, so we add the carry to acc (i.e., increase by
5388 + one). */
5389 + ++acc;
5390 + }
5391 + ++sdata;
5392 + }
5393 +
5394 + /* add up any odd byte */
5395 + if(len == 1) {
5396 + acc += htons(((u16_t)(*(u8_t *)sdata)) << 8);
5397 + if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) {
5398 + ++acc;
5399 + }
5400 + }
5401 +
5402 + return acc;
5403 +}
5404 +/*-----------------------------------------------------------------------------------*/
5405 +u16_t
5406 +uip_ipchksum(void)
5407 +{
5408 + return uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN], 20);
5409 +}
5410 +/*-----------------------------------------------------------------------------------*/
5411 +u16_t
5412 +uip_tcpchksum(void)
5413 +{
5414 + u16_t hsum, sum;
5415 +
5416 +
5417 + /* Compute the checksum of the TCP header. */
5418 + hsum = uip_chksum((u16_t *)&uip_buf[20 + UIP_LLH_LEN], 20);
5419 +
5420 + /* Compute the checksum of the data in the TCP packet and add it to
5421 + the TCP header checksum. */
5422 + sum = uip_chksum((u16_t *)uip_appdata,
5423 + (u16_t)(((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 40)));
5424 +
5425 + if((sum += hsum) < hsum) {
5426 + ++sum;
5427 + }
5428 +
5429 + if((sum += BUF->srcipaddr[0]) < BUF->srcipaddr[0]) {
5430 + ++sum;
5431 + }
5432 + if((sum += BUF->srcipaddr[1]) < BUF->srcipaddr[1]) {
5433 + ++sum;
5434 + }
5435 + if((sum += BUF->destipaddr[0]) < BUF->destipaddr[0]) {
5436 + ++sum;
5437 + }
5438 + if((sum += BUF->destipaddr[1]) < BUF->destipaddr[1]) {
5439 + ++sum;
5440 + }
5441 + if((sum += (u16_t)htons((u16_t)IP_PROTO_TCP)) < (u16_t)htons((u16_t)IP_PROTO_TCP)) {
5442 + ++sum;
5443 + }
5444 +
5445 + hsum = (u16_t)htons((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 20);
5446 +
5447 + if((sum += hsum) < hsum) {
5448 + ++sum;
5449 + }
5450 +
5451 + return sum;
5452 +}
5453 +/*-----------------------------------------------------------------------------------*/
5454 --- /dev/null
5455 +++ b/net/uip-0.9/uip_arch.h
5456 @@ -0,0 +1,130 @@
5457 +/**
5458 + * \defgroup uiparch Architecture specific uIP functions
5459 + * @{
5460 + *
5461 + * The functions in the architecture specific module implement the IP
5462 + * check sum and 32-bit additions.
5463 + *
5464 + * The IP checksum calculation is the most computationally expensive
5465 + * operation in the TCP/IP stack and it therefore pays off to
5466 + * implement this in efficient assembler. The purpose of the uip-arch
5467 + * module is to let the checksum functions to be implemented in
5468 + * architecture specific assembler.
5469 + *
5470 + */
5471 +
5472 +/**
5473 + * \file
5474 + * Declarations of architecture specific functions.
5475 + * \author Adam Dunkels <adam@dunkels.com>
5476 + */
5477 +
5478 +/*
5479 + * Copyright (c) 2001, Adam Dunkels.
5480 + * All rights reserved.
5481 + *
5482 + * Redistribution and use in source and binary forms, with or without
5483 + * modification, are permitted provided that the following conditions
5484 + * are met:
5485 + * 1. Redistributions of source code must retain the above copyright
5486 + * notice, this list of conditions and the following disclaimer.
5487 + * 2. Redistributions in binary form must reproduce the above copyright
5488 + * notice, this list of conditions and the following disclaimer in the
5489 + * documentation and/or other materials provided with the distribution.
5490 + * 3. The name of the author may not be used to endorse or promote
5491 + * products derived from this software without specific prior
5492 + * written permission.
5493 + *
5494 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5495 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5496 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5497 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5498 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5499 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5500 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5501 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5502 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5503 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5504 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5505 + *
5506 + * This file is part of the uIP TCP/IP stack.
5507 + *
5508 + * $Id: uip_arch.h,v 1.1.2.2 2003/10/06 15:10:22 adam Exp $
5509 + *
5510 + */
5511 +
5512 +#ifndef __UIP_ARCH_H__
5513 +#define __UIP_ARCH_H__
5514 +
5515 +#include "uip.h"
5516 +
5517 +/**
5518 + * Carry out a 32-bit addition.
5519 + *
5520 + * Because not all architectures for which uIP is intended has native
5521 + * 32-bit arithmetic, uIP uses an external C function for doing the
5522 + * required 32-bit additions in the TCP protocol processing. This
5523 + * function should add the two arguments and place the result in the
5524 + * global variable uip_acc32.
5525 + *
5526 + * \note The 32-bit integer pointed to by the op32 parameter and the
5527 + * result in the uip_acc32 variable are in network byte order (big
5528 + * endian).
5529 + *
5530 + * \param op32 A pointer to a 4-byte array representing a 32-bit
5531 + * integer in network byte order (big endian).
5532 + *
5533 + * \param op16 A 16-bit integer in host byte order.
5534 + */
5535 +void uip_add32(u8_t *op32, u16_t op16);
5536 +
5537 +/**
5538 + * Calculate the Internet checksum over a buffer.
5539 + *
5540 + * The Internet checksum is the one's complement of the one's
5541 + * complement sum of all 16-bit words in the buffer.
5542 + *
5543 + * See RFC1071.
5544 + *
5545 + * \note This function is not called in the current version of uIP,
5546 + * but future versions might make use of it.
5547 + *
5548 + * \param buf A pointer to the buffer over which the checksum is to be
5549 + * computed.
5550 + *
5551 + * \param len The length of the buffer over which the checksum is to
5552 + * be computed.
5553 + *
5554 + * \return The Internet checksum of the buffer.
5555 + */
5556 +u16_t uip_chksum(u16_t *buf, u16_t len);
5557 +
5558 +/**
5559 + * Calculate the IP header checksum of the packet header in uip_buf.
5560 + *
5561 + * The IP header checksum is the Internet checksum of the 20 bytes of
5562 + * the IP header.
5563 + *
5564 + * \return The IP header checksum of the IP header in the uip_buf
5565 + * buffer.
5566 + */
5567 +u16_t uip_ipchksum(void);
5568 +
5569 +/**
5570 + * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
5571 + *
5572 + * The TCP checksum is the Internet checksum of data contents of the
5573 + * TCP segment, and a pseudo-header as defined in RFC793.
5574 + *
5575 + * \note The uip_appdata pointer that points to the packet data may
5576 + * point anywhere in memory, so it is not possible to simply calculate
5577 + * the Internet checksum of the contents of the uip_buf buffer.
5578 + *
5579 + * \return The TCP checksum of the TCP segment in uip_buf and pointed
5580 + * to by uip_appdata.
5581 + */
5582 +u16_t uip_tcpchksum(void);
5583 +
5584 +/** @} */
5585 +
5586 +#endif /* __UIP_ARCH_H__ */
5587 --- /dev/null
5588 +++ b/net/uip-0.9/uip_arp.c
5589 @@ -0,0 +1,421 @@
5590 +/**
5591 + * \addtogroup uip
5592 + * @{
5593 + */
5594 +
5595 +/**
5596 + * \defgroup uiparp uIP Address Resolution Protocol
5597 + * @{
5598 + *
5599 + * The Address Resolution Protocol ARP is used for mapping between IP
5600 + * addresses and link level addresses such as the Ethernet MAC
5601 + * addresses. ARP uses broadcast queries to ask for the link level
5602 + * address of a known IP address and the host which is configured with
5603 + * the IP address for which the query was meant, will respond with its
5604 + * link level address.
5605 + *
5606 + * \note This ARP implementation only supports Ethernet.
5607 + */
5608 +
5609 +/**
5610 + * \file
5611 + * Implementation of the ARP Address Resolution Protocol.
5612 + * \author Adam Dunkels <adam@dunkels.com>
5613 + *
5614 + */
5615 +
5616 +/*
5617 + * Copyright (c) 2001-2003, Adam Dunkels.
5618 + * All rights reserved.
5619 + *
5620 + * Redistribution and use in source and binary forms, with or without
5621 + * modification, are permitted provided that the following conditions
5622 + * are met:
5623 + * 1. Redistributions of source code must retain the above copyright
5624 + * notice, this list of conditions and the following disclaimer.
5625 + * 2. Redistributions in binary form must reproduce the above copyright
5626 + * notice, this list of conditions and the following disclaimer in the
5627 + * documentation and/or other materials provided with the distribution.
5628 + * 3. The name of the author may not be used to endorse or promote
5629 + * products derived from this software without specific prior
5630 + * written permission.
5631 + *
5632 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5633 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5634 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5635 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5636 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5637 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5638 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5639 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5640 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5641 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5642 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5643 + *
5644 + * This file is part of the uIP TCP/IP stack.
5645 + *
5646 + * $Id: uip_arp.c,v 1.7.2.3 2003/10/06 22:42:30 adam Exp $
5647 + *
5648 + */
5649 +
5650 +
5651 +#include "uip_arp.h"
5652 +
5653 +struct arp_hdr {
5654 + struct uip_eth_hdr ethhdr;
5655 + u16_t hwtype;
5656 + u16_t protocol;
5657 + u8_t hwlen;
5658 + u8_t protolen;
5659 + u16_t opcode;
5660 + struct uip_eth_addr shwaddr;
5661 + u16_t sipaddr[2];
5662 + struct uip_eth_addr dhwaddr;
5663 + u16_t dipaddr[2];
5664 +};
5665 +
5666 +struct ethip_hdr {
5667 + struct uip_eth_hdr ethhdr;
5668 + /* IP header. */
5669 + u8_t vhl,
5670 + tos,
5671 + len[2],
5672 + ipid[2],
5673 + ipoffset[2],
5674 + ttl,
5675 + proto;
5676 + u16_t ipchksum;
5677 + u16_t srcipaddr[2],
5678 + destipaddr[2];
5679 +};
5680 +
5681 +#define ARP_REQUEST 1
5682 +#define ARP_REPLY 2
5683 +
5684 +#define ARP_HWTYPE_ETH 1
5685 +
5686 +struct arp_entry {
5687 + u16_t ipaddr[2];
5688 + struct uip_eth_addr ethaddr;
5689 + u8_t time;
5690 +};
5691 +
5692 +struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
5693 + UIP_ETHADDR1,
5694 + UIP_ETHADDR2,
5695 + UIP_ETHADDR3,
5696 + UIP_ETHADDR4,
5697 + UIP_ETHADDR5}};
5698 +
5699 +static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
5700 +static u16_t ipaddr[2];
5701 +static u8_t i, c;
5702 +
5703 +static u8_t arptime;
5704 +static u8_t tmpage;
5705 +
5706 +#define BUF ((struct arp_hdr *)&uip_buf[0])
5707 +#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
5708 +/*-----------------------------------------------------------------------------------*/
5709 +/**
5710 + * Initialize the ARP module.
5711 + *
5712 + */
5713 +/*-----------------------------------------------------------------------------------*/
5714 +void
5715 +uip_arp_init(void)
5716 +{
5717 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
5718 + memset(arp_table[i].ipaddr, 0, 4);
5719 + }
5720 +}
5721 +/*-----------------------------------------------------------------------------------*/
5722 +/**
5723 + * Periodic ARP processing function.
5724 + *
5725 + * This function performs periodic timer processing in the ARP module
5726 + * and should be called at regular intervals. The recommended interval
5727 + * is 10 seconds between the calls.
5728 + *
5729 + */
5730 +/*-----------------------------------------------------------------------------------*/
5731 +void
5732 +uip_arp_timer(void)
5733 +{
5734 + struct arp_entry *tabptr;
5735 +
5736 + ++arptime;
5737 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
5738 + tabptr = &arp_table[i];
5739 + if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
5740 + arptime - tabptr->time >= UIP_ARP_MAXAGE) {
5741 + memset(tabptr->ipaddr, 0, 4);
5742 + }
5743 + }
5744 +
5745 +}
5746 +/*-----------------------------------------------------------------------------------*/
5747 +static void
5748 +uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
5749 +{
5750 + register struct arp_entry *tabptr;
5751 + /* Walk through the ARP mapping table and try to find an entry to
5752 + update. If none is found, the IP -> MAC address mapping is
5753 + inserted in the ARP table. */
5754 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
5755 +
5756 + tabptr = &arp_table[i];
5757 + /* Only check those entries that are actually in use. */
5758 + if(tabptr->ipaddr[0] != 0 &&
5759 + tabptr->ipaddr[1] != 0) {
5760 +
5761 + /* Check if the source IP address of the incoming packet matches
5762 + the IP address in this ARP table entry. */
5763 + if(ipaddr[0] == tabptr->ipaddr[0] &&
5764 + ipaddr[1] == tabptr->ipaddr[1]) {
5765 +
5766 + /* An old entry found, update this and return. */
5767 + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
5768 + tabptr->time = arptime;
5769 +
5770 + return;
5771 + }
5772 + }
5773 + }
5774 +
5775 + /* If we get here, no existing ARP table entry was found, so we
5776 + create one. */
5777 +
5778 + /* First, we try to find an unused entry in the ARP table. */
5779 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
5780 + tabptr = &arp_table[i];
5781 + if(tabptr->ipaddr[0] == 0 &&
5782 + tabptr->ipaddr[1] == 0) {
5783 + break;
5784 + }
5785 + }
5786 +
5787 + /* If no unused entry is found, we try to find the oldest entry and
5788 + throw it away. */
5789 + if(i == UIP_ARPTAB_SIZE) {
5790 + tmpage = 0;
5791 + c = 0;
5792 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
5793 + tabptr = &arp_table[i];
5794 + if(arptime - tabptr->time > tmpage) {
5795 + tmpage = arptime - tabptr->time;
5796 + c = i;
5797 + }
5798 + }
5799 + i = c;
5800 + }
5801 +
5802 + /* Now, i is the ARP table entry which we will fill with the new
5803 + information. */
5804 + memcpy(tabptr->ipaddr, ipaddr, 4);
5805 + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
5806 + tabptr->time = arptime;
5807 +}
5808 +/*-----------------------------------------------------------------------------------*/
5809 +/**
5810 + * ARP processing for incoming IP packets
5811 + *
5812 + * This function should be called by the device driver when an IP
5813 + * packet has been received. The function will check if the address is
5814 + * in the ARP cache, and if so the ARP cache entry will be
5815 + * refreshed. If no ARP cache entry was found, a new one is created.
5816 + *
5817 + * This function expects an IP packet with a prepended Ethernet header
5818 + * in the uip_buf[] buffer, and the length of the packet in the global
5819 + * variable uip_len.
5820 + */
5821 +/*-----------------------------------------------------------------------------------*/
5822 +void
5823 +uip_arp_ipin(void)
5824 +{
5825 + uip_len -= sizeof(struct uip_eth_hdr);
5826 +
5827 + /* Only insert/update an entry if the source IP address of the
5828 + incoming IP packet comes from a host on the local network. */
5829 + if((IPBUF->srcipaddr[0] & uip_arp_netmask[0]) !=
5830 + (uip_hostaddr[0] & uip_arp_netmask[0])) {
5831 + return;
5832 + }
5833 + if((IPBUF->srcipaddr[1] & uip_arp_netmask[1]) !=
5834 + (uip_hostaddr[1] & uip_arp_netmask[1])) {
5835 + return;
5836 + }
5837 + uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
5838 +
5839 + return;
5840 +}
5841 +/*-----------------------------------------------------------------------------------*/
5842 +/**
5843 + * ARP processing for incoming ARP packets.
5844 + *
5845 + * This function should be called by the device driver when an ARP
5846 + * packet has been received. The function will act differently
5847 + * depending on the ARP packet type: if it is a reply for a request
5848 + * that we previously sent out, the ARP cache will be filled in with
5849 + * the values from the ARP reply. If the incoming ARP packet is an ARP
5850 + * request for our IP address, an ARP reply packet is created and put
5851 + * into the uip_buf[] buffer.
5852 + *
5853 + * When the function returns, the value of the global variable uip_len
5854 + * indicates whether the device driver should send out a packet or
5855 + * not. If uip_len is zero, no packet should be sent. If uip_len is
5856 + * non-zero, it contains the length of the outbound packet that is
5857 + * present in the uip_buf[] buffer.
5858 + *
5859 + * This function expects an ARP packet with a prepended Ethernet
5860 + * header in the uip_buf[] buffer, and the length of the packet in the
5861 + * global variable uip_len.
5862 + */
5863 +/*-----------------------------------------------------------------------------------*/
5864 +void
5865 +uip_arp_arpin(void)
5866 +{
5867 +
5868 + if(uip_len < sizeof(struct arp_hdr)) {
5869 + uip_len = 0;
5870 + return;
5871 + }
5872 +
5873 + uip_len = 0;
5874 +
5875 + switch(BUF->opcode) {
5876 + case HTONS(ARP_REQUEST):
5877 + /* ARP request. If it asked for our address, we send out a
5878 + reply. */
5879 + if(BUF->dipaddr[0] == uip_hostaddr[0] &&
5880 + BUF->dipaddr[1] == uip_hostaddr[1]) {
5881 + /* The reply opcode is 2. */
5882 + BUF->opcode = HTONS(2);
5883 +
5884 + memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
5885 + memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
5886 + memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
5887 + memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
5888 +
5889 + BUF->dipaddr[0] = BUF->sipaddr[0];
5890 + BUF->dipaddr[1] = BUF->sipaddr[1];
5891 + BUF->sipaddr[0] = uip_hostaddr[0];
5892 + BUF->sipaddr[1] = uip_hostaddr[1];
5893 +
5894 + BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
5895 + uip_len = sizeof(struct arp_hdr);
5896 + }
5897 + break;
5898 + case HTONS(ARP_REPLY):
5899 + /* ARP reply. We insert or update the ARP table if it was meant
5900 + for us. */
5901 + if(BUF->dipaddr[0] == uip_hostaddr[0] &&
5902 + BUF->dipaddr[1] == uip_hostaddr[1]) {
5903 +
5904 + uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
5905 + }
5906 + break;
5907 + }
5908 +
5909 + return;
5910 +}
5911 +/*-----------------------------------------------------------------------------------*/
5912 +/**
5913 + * Prepend Ethernet header to an outbound IP packet and see if we need
5914 + * to send out an ARP request.
5915 + *
5916 + * This function should be called before sending out an IP packet. The
5917 + * function checks the destination IP address of the IP packet to see
5918 + * what Ethernet MAC address that should be used as a destination MAC
5919 + * address on the Ethernet.
5920 + *
5921 + * If the destination IP address is in the local network (determined
5922 + * by logical ANDing of netmask and our IP address), the function
5923 + * checks the ARP cache to see if an entry for the destination IP
5924 + * address is found. If so, an Ethernet header is prepended and the
5925 + * function returns. If no ARP cache entry is found for the
5926 + * destination IP address, the packet in the uip_buf[] is replaced by
5927 + * an ARP request packet for the IP address. The IP packet is dropped
5928 + * and it is assumed that they higher level protocols (e.g., TCP)
5929 + * eventually will retransmit the dropped packet.
5930 + *
5931 + * If the destination IP address is not on the local network, the IP
5932 + * address of the default router is used instead.
5933 + *
5934 + * When the function returns, a packet is present in the uip_buf[]
5935 + * buffer, and the length of the packet is in the global variable
5936 + * uip_len.
5937 + */
5938 +/*-----------------------------------------------------------------------------------*/
5939 +void
5940 +uip_arp_out(void)
5941 +{
5942 + struct arp_entry *tabptr;
5943 + /* Find the destination IP address in the ARP table and construct
5944 + the Ethernet header. If the destination IP addres isn't on the
5945 + local network, we use the default router's IP address instead.
5946 +
5947 + If not ARP table entry is found, we overwrite the original IP
5948 + packet with an ARP request for the IP address. */
5949 +
5950 + /* Check if the destination address is on the local network. */
5951 + if((IPBUF->destipaddr[0] & uip_arp_netmask[0]) !=
5952 + (uip_hostaddr[0] & uip_arp_netmask[0]) ||
5953 + (IPBUF->destipaddr[1] & uip_arp_netmask[1]) !=
5954 + (uip_hostaddr[1] & uip_arp_netmask[1])) {
5955 + /* Destination address was not on the local network, so we need to
5956 + use the default router's IP address instead of the destination
5957 + address when determining the MAC address. */
5958 + ipaddr[0] = uip_arp_draddr[0];
5959 + ipaddr[1] = uip_arp_draddr[1];
5960 + } else {
5961 + /* Else, we use the destination IP address. */
5962 + ipaddr[0] = IPBUF->destipaddr[0];
5963 + ipaddr[1] = IPBUF->destipaddr[1];
5964 + }
5965 +
5966 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
5967 + tabptr = &arp_table[i];
5968 + if(ipaddr[0] == tabptr->ipaddr[0] &&
5969 + ipaddr[1] == tabptr->ipaddr[1])
5970 + break;
5971 + }
5972 +
5973 + if(i == UIP_ARPTAB_SIZE) {
5974 + /* The destination address was not in our ARP table, so we
5975 + overwrite the IP packet with an ARP request. */
5976 +
5977 + memset(BUF->ethhdr.dest.addr, 0xff, 6);
5978 + memset(BUF->dhwaddr.addr, 0x00, 6);
5979 + memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
5980 + memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
5981 +
5982 + BUF->dipaddr[0] = ipaddr[0];
5983 + BUF->dipaddr[1] = ipaddr[1];
5984 + BUF->sipaddr[0] = uip_hostaddr[0];
5985 + BUF->sipaddr[1] = uip_hostaddr[1];
5986 + BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
5987 + BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
5988 + BUF->protocol = HTONS(UIP_ETHTYPE_IP);
5989 + BUF->hwlen = 6;
5990 + BUF->protolen = 4;
5991 + BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
5992 +
5993 + uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
5994 +
5995 + uip_len = sizeof(struct arp_hdr);
5996 + return;
5997 + }
5998 +
5999 + /* Build an ethernet header. */
6000 + memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
6001 + memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
6002 +
6003 + IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
6004 +
6005 + uip_len += sizeof(struct uip_eth_hdr);
6006 +}
6007 +/*-----------------------------------------------------------------------------------*/
6008 +
6009 +/** @} */
6010 +/** @} */
6011 --- /dev/null
6012 +++ b/net/uip-0.9/uip_arp.h
6013 @@ -0,0 +1,201 @@
6014 +/**
6015 + * \addtogroup uip
6016 + * @{
6017 + */
6018 +
6019 +/**
6020 + * \addtogroup uiparp
6021 + * @{
6022 + */
6023 +
6024 +/**
6025 + * \file
6026 + * Macros and definitions for the ARP module.
6027 + * \author Adam Dunkels <adam@dunkels.com>
6028 + */
6029 +
6030 +
6031 +/*
6032 + * Copyright (c) 2001-2003, Adam Dunkels.
6033 + * All rights reserved.
6034 + *
6035 + * Redistribution and use in source and binary forms, with or without
6036 + * modification, are permitted provided that the following conditions
6037 + * are met:
6038 + * 1. Redistributions of source code must retain the above copyright
6039 + * notice, this list of conditions and the following disclaimer.
6040 + * 2. Redistributions in binary form must reproduce the above copyright
6041 + * notice, this list of conditions and the following disclaimer in the
6042 + * documentation and/or other materials provided with the distribution.
6043 + * 3. The name of the author may not be used to endorse or promote
6044 + * products derived from this software without specific prior
6045 + * written permission.
6046 + *
6047 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
6048 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6049 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6050 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
6051 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6052 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
6053 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
6054 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
6055 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
6056 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6057 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6058 + *
6059 + * This file is part of the uIP TCP/IP stack.
6060 + *
6061 + * $Id: uip_arp.h,v 1.3.2.2 2003/10/06 15:10:22 adam Exp $
6062 + *
6063 + */
6064 +
6065 +#ifndef __UIP_ARP_H__
6066 +#define __UIP_ARP_H__
6067 +
6068 +#include "uip.h"
6069 +
6070 +
6071 +/**
6072 + * Representation of a 48-bit Ethernet address.
6073 + */
6074 +struct uip_eth_addr {
6075 + u8_t addr[6];
6076 +};
6077 +
6078 +extern struct uip_eth_addr uip_ethaddr;
6079 +
6080 +/**
6081 + * The Ethernet header.
6082 + */
6083 +struct uip_eth_hdr {
6084 + struct uip_eth_addr dest;
6085 + struct uip_eth_addr src;
6086 + u16_t type;
6087 +};
6088 +
6089 +#define UIP_ETHTYPE_ARP 0x0806
6090 +#define UIP_ETHTYPE_IP 0x0800
6091 +#define UIP_ETHTYPE_IP6 0x86dd
6092 +
6093 +
6094 +/* The uip_arp_init() function must be called before any of the other
6095 + ARP functions. */
6096 +void uip_arp_init(void);
6097 +
6098 +/* The uip_arp_ipin() function should be called whenever an IP packet
6099 + arrives from the Ethernet. This function refreshes the ARP table or
6100 + inserts a new mapping if none exists. The function assumes that an
6101 + IP packet with an Ethernet header is present in the uip_buf buffer
6102 + and that the length of the packet is in the uip_len variable. */
6103 +void uip_arp_ipin(void);
6104 +
6105 +/* The uip_arp_arpin() should be called when an ARP packet is received
6106 + by the Ethernet driver. This function also assumes that the
6107 + Ethernet frame is present in the uip_buf buffer. When the
6108 + uip_arp_arpin() function returns, the contents of the uip_buf
6109 + buffer should be sent out on the Ethernet if the uip_len variable
6110 + is > 0. */
6111 +void uip_arp_arpin(void);
6112 +
6113 +/* The uip_arp_out() function should be called when an IP packet
6114 + should be sent out on the Ethernet. This function creates an
6115 + Ethernet header before the IP header in the uip_buf buffer. The
6116 + Ethernet header will have the correct Ethernet MAC destination
6117 + address filled in if an ARP table entry for the destination IP
6118 + address (or the IP address of the default router) is present. If no
6119 + such table entry is found, the IP packet is overwritten with an ARP
6120 + request and we rely on TCP to retransmit the packet that was
6121 + overwritten. In any case, the uip_len variable holds the length of
6122 + the Ethernet frame that should be transmitted. */
6123 +void uip_arp_out(void);
6124 +
6125 +/* The uip_arp_timer() function should be called every ten seconds. It
6126 + is responsible for flushing old entries in the ARP table. */
6127 +void uip_arp_timer(void);
6128 +
6129 +/** @} */
6130 +
6131 +/**
6132 + * \addtogroup uipconffunc
6133 + * @{
6134 + */
6135 +
6136 +/**
6137 + * Set the default router's IP address.
6138 + *
6139 + * \param addr A pointer to a 4-byte array containing the IP address
6140 + * of the default router.
6141 + *
6142 + * \hideinitializer
6143 + */
6144 +#define uip_setdraddr(addr) do { uip_arp_draddr[0] = addr[0]; \
6145 + uip_arp_draddr[1] = addr[1]; } while(0)
6146 +
6147 +/**
6148 + * Set the netmask.
6149 + *
6150 + * \param addr A pointer to a 4-byte array containing the IP address
6151 + * of the netmask.
6152 + *
6153 + * \hideinitializer
6154 + */
6155 +#define uip_setnetmask(addr) do { uip_arp_netmask[0] = addr[0]; \
6156 + uip_arp_netmask[1] = addr[1]; } while(0)
6157 +
6158 +
6159 +/**
6160 + * Get the default router's IP address.
6161 + *
6162 + * \param addr A pointer to a 4-byte array that will be filled in with
6163 + * the IP address of the default router.
6164 + *
6165 + * \hideinitializer
6166 + */
6167 +#define uip_getdraddr(addr) do { addr[0] = uip_arp_draddr[0]; \
6168 + addr[1] = uip_arp_draddr[1]; } while(0)
6169 +
6170 +/**
6171 + * Get the netmask.
6172 + *
6173 + * \param addr A pointer to a 4-byte array that will be filled in with
6174 + * the value of the netmask.
6175 + *
6176 + * \hideinitializer
6177 + */
6178 +#define uip_getnetmask(addr) do { addr[0] = uip_arp_netmask[0]; \
6179 + addr[1] = uip_arp_netmask[1]; } while(0)
6180 +
6181 +
6182 +/**
6183 + * Specifiy the Ethernet MAC address.
6184 + *
6185 + * The ARP code needs to know the MAC address of the Ethernet card in
6186 + * order to be able to respond to ARP queries and to generate working
6187 + * Ethernet headers.
6188 + *
6189 + * \note This macro only specifies the Ethernet MAC address to the ARP
6190 + * code. It cannot be used to change the MAC address of the Ethernet
6191 + * card.
6192 + *
6193 + * \param eaddr A pointer to a struct uip_eth_addr containing the
6194 + * Ethernet MAC address of the Ethernet card.
6195 + *
6196 + * \hideinitializer
6197 + */
6198 +#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \
6199 + uip_ethaddr.addr[1] = eaddr.addr[1];\
6200 + uip_ethaddr.addr[2] = eaddr.addr[2];\
6201 + uip_ethaddr.addr[3] = eaddr.addr[3];\
6202 + uip_ethaddr.addr[4] = eaddr.addr[4];\
6203 + uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)
6204 +
6205 +/** @} */
6206 +
6207 +/**
6208 + * \internal Internal variables that are set using the macros
6209 + * uip_setdraddr and uip_setnetmask.
6210 + */
6211 +extern u16_t uip_arp_draddr[2], uip_arp_netmask[2];
6212 +#endif /* __UIP_ARP_H__ */
6213 +
6214 +
6215 --- /dev/null
6216 +++ b/net/uip-0.9/uip.c
6217 @@ -0,0 +1,1503 @@
6218 +/**
6219 + * \addtogroup uip
6220 + * @{
6221 + */
6222 +
6223 +/**
6224 + * \file
6225 + * The uIP TCP/IP stack code.
6226 + * \author Adam Dunkels <adam@dunkels.com>
6227 + */
6228 +
6229 +/*
6230 + * Copyright (c) 2001-2003, Adam Dunkels.
6231 + * All rights reserved.
6232 + *
6233 + * Redistribution and use in source and binary forms, with or without
6234 + * modification, are permitted provided that the following conditions
6235 + * are met:
6236 + * 1. Redistributions of source code must retain the above copyright
6237 + * notice, this list of conditions and the following disclaimer.
6238 + * 2. Redistributions in binary form must reproduce the above copyright
6239 + * notice, this list of conditions and the following disclaimer in the
6240 + * documentation and/or other materials provided with the distribution.
6241 + * 3. The name of the author may not be used to endorse or promote
6242 + * products derived from this software without specific prior
6243 + * written permission.
6244 + *
6245 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
6246 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6247 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6248 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
6249 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6250 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
6251 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
6252 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
6253 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
6254 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6255 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6256 + *
6257 + * This file is part of the uIP TCP/IP stack.
6258 + *
6259 + * $Id: uip.c,v 1.62.2.10 2003/10/07 13:23:01 adam Exp $
6260 + *
6261 + */
6262 +
6263 +/*
6264 +This is a small implementation of the IP and TCP protocols (as well as
6265 +some basic ICMP stuff). The implementation couples the IP, TCP and the
6266 +application layers very tightly. To keep the size of the compiled code
6267 +down, this code also features heavy usage of the goto statement.
6268 +
6269 +The principle is that we have a small buffer, called the uip_buf, in
6270 +which the device driver puts an incoming packet. The TCP/IP stack
6271 +parses the headers in the packet, and calls upon the application. If
6272 +the remote host has sent data to the application, this data is present
6273 +in the uip_buf and the application read the data from there. It is up
6274 +to the application to put this data into a byte stream if needed. The
6275 +application will not be fed with data that is out of sequence.
6276 +
6277 +If the application whishes to send data to the peer, it should put its
6278 +data into the uip_buf, 40 bytes from the start of the buffer. The
6279 +TCP/IP stack will calculate the checksums, and fill in the necessary
6280 +header fields and finally send the packet back to the peer.
6281 +*/
6282 +
6283 +#include "uip.h"
6284 +#include "uipopt.h"
6285 +#include "uip_arch.h"
6286 +
6287 +/*-----------------------------------------------------------------------------------*/
6288 +/* Variable definitions. */
6289 +
6290 +
6291 +/* The IP address of this host. If it is defined to be fixed (by setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set here. Otherwise, the address */
6292 +#if UIP_FIXEDADDR > 0
6293 +const unsigned short int uip_hostaddr[2] =
6294 + {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
6295 + HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
6296 +const unsigned short int uip_arp_draddr[2] =
6297 + {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
6298 + HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
6299 +const unsigned short int uip_arp_netmask[2] =
6300 + {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
6301 + HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
6302 +#else
6303 +unsigned short int uip_hostaddr[2];
6304 +unsigned short int uip_arp_draddr[2], uip_arp_netmask[2];
6305 +#endif /* UIP_FIXEDADDR */
6306 +
6307 +u8_t uip_buf[UIP_BUFSIZE+2]; /* The packet buffer that contains
6308 + incoming packets. */
6309 +volatile u8_t *uip_appdata; /* The uip_appdata pointer points to
6310 + application data. */
6311 +volatile u8_t *uip_sappdata; /* The uip_appdata pointer points to the
6312 + application data which is to be sent. */
6313 +#if UIP_URGDATA > 0
6314 +volatile u8_t *uip_urgdata; /* The uip_urgdata pointer points to
6315 + urgent data (out-of-band data), if
6316 + present. */
6317 +volatile u8_t uip_urglen, uip_surglen;
6318 +#endif /* UIP_URGDATA > 0 */
6319 +
6320 +volatile unsigned short int uip_len, uip_slen;
6321 + /* The uip_len is either 8 or 16 bits,
6322 + depending on the maximum packet
6323 + size. */
6324 +
6325 +volatile u8_t uip_flags; /* The uip_flags variable is used for
6326 + communication between the TCP/IP stack
6327 + and the application program. */
6328 +struct uip_conn *uip_conn; /* uip_conn always points to the current
6329 + connection. */
6330 +
6331 +struct uip_conn uip_conns[UIP_CONNS];
6332 + /* The uip_conns array holds all TCP
6333 + connections. */
6334 +unsigned short int uip_listenports[UIP_LISTENPORTS];
6335 + /* The uip_listenports list all currently
6336 + listning ports. */
6337 +#if UIP_UDP
6338 +struct uip_udp_conn *uip_udp_conn;
6339 +struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
6340 +#endif /* UIP_UDP */
6341 +
6342 +
6343 +static unsigned short int ipid; /* Ths ipid variable is an increasing
6344 + number that is used for the IP ID
6345 + field. */
6346 +
6347 +static u8_t iss[4]; /* The iss variable is used for the TCP
6348 + initial sequence number. */
6349 +
6350 +#if UIP_ACTIVE_OPEN
6351 +static unsigned short int lastport; /* Keeps track of the last port used for
6352 + a new connection. */
6353 +#endif /* UIP_ACTIVE_OPEN */
6354 +
6355 +/* Temporary variables. */
6356 +volatile u8_t uip_acc32[4];
6357 +static u8_t c, opt;
6358 +static unsigned short int tmp16;
6359 +
6360 +/* Structures and definitions. */
6361 +#define TCP_FIN 0x01
6362 +#define TCP_SYN 0x02
6363 +#define TCP_RST 0x04
6364 +#define TCP_PSH 0x08
6365 +#define TCP_ACK 0x10
6366 +#define TCP_URG 0x20
6367 +#define TCP_CTL 0x3f
6368 +
6369 +#define ICMP_ECHO_REPLY 0
6370 +#define ICMP_ECHO 8
6371 +
6372 +/* Macros. */
6373 +#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
6374 +#define FBUF ((uip_tcpip_hdr *)&uip_reassbuf[0])
6375 +#define ICMPBUF ((uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
6376 +#define UDPBUF ((uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
6377 +
6378 +#if UIP_STATISTICS == 1
6379 +struct uip_stats uip_stat;
6380 +#define UIP_STAT(s) s
6381 +#else
6382 +#define UIP_STAT(s)
6383 +#endif /* UIP_STATISTICS == 1 */
6384 +
6385 +#if UIP_LOGGING == 1
6386 +extern void puts(const char *s);
6387 +#define UIP_LOG(m) puts(m)
6388 +#else
6389 +#define UIP_LOG(m)
6390 +#endif /* UIP_LOGGING == 1 */
6391 +
6392 +/*-----------------------------------------------------------------------------------*/
6393 +void
6394 +uip_init(void)
6395 +{
6396 + for(c = 0; c < UIP_LISTENPORTS; ++c) {
6397 + uip_listenports[c] = 0;
6398 + }
6399 + for(c = 0; c < UIP_CONNS; ++c) {
6400 + uip_conns[c].tcpstateflags = CLOSED;
6401 + }
6402 +#if UIP_ACTIVE_OPEN
6403 + lastport = 1024;
6404 +#endif /* UIP_ACTIVE_OPEN */
6405 +
6406 +#if UIP_UDP
6407 + for(c = 0; c < UIP_UDP_CONNS; ++c) {
6408 + uip_udp_conns[c].lport = 0;
6409 + }
6410 +#endif /* UIP_UDP */
6411 +
6412 +
6413 + /* IPv4 initialization. */
6414 +#if UIP_FIXEDADDR == 0
6415 + uip_hostaddr[0] = uip_hostaddr[1] = 0;
6416 +#endif /* UIP_FIXEDADDR */
6417 +
6418 +}
6419 +/*-----------------------------------------------------------------------------------*/
6420 +#if UIP_ACTIVE_OPEN
6421 +struct uip_conn *
6422 +uip_connect(unsigned short int *ripaddr, unsigned short int rport)
6423 +{
6424 + register struct uip_conn *conn, *cconn;
6425 +
6426 + /* Find an unused local port. */
6427 + again:
6428 + ++lastport;
6429 +
6430 + if(lastport >= 32000) {
6431 + lastport = 4096;
6432 + }
6433 +
6434 + /* Check if this port is already in use, and if so try to find
6435 + another one. */
6436 + for(c = 0; c < UIP_CONNS; ++c) {
6437 + conn = &uip_conns[c];
6438 + if(conn->tcpstateflags != CLOSED &&
6439 + conn->lport == htons(lastport)) {
6440 + goto again;
6441 + }
6442 + }
6443 +
6444 +
6445 + conn = 0;
6446 + for(c = 0; c < UIP_CONNS; ++c) {
6447 + cconn = &uip_conns[c];
6448 + if(cconn->tcpstateflags == CLOSED) {
6449 + conn = cconn;
6450 + break;
6451 + }
6452 + if(cconn->tcpstateflags == TIME_WAIT) {
6453 + if(conn == 0 ||
6454 + cconn->timer > uip_conn->timer) {
6455 + conn = cconn;
6456 + }
6457 + }
6458 + }
6459 +
6460 + if(conn == 0) {
6461 + return 0;
6462 + }
6463 +
6464 + conn->tcpstateflags = SYN_SENT;
6465 +
6466 + conn->snd_nxt[0] = iss[0];
6467 + conn->snd_nxt[1] = iss[1];
6468 + conn->snd_nxt[2] = iss[2];
6469 + conn->snd_nxt[3] = iss[3];
6470 +
6471 + conn->initialmss = conn->mss = UIP_TCP_MSS;
6472 +
6473 + conn->len = 1; /* TCP length of the SYN is one. */
6474 + conn->nrtx = 0;
6475 + conn->timer = 1; /* Send the SYN next time around. */
6476 + conn->rto = UIP_RTO;
6477 + conn->sa = 0;
6478 + conn->sv = 16;
6479 + conn->lport = htons(lastport);
6480 + conn->rport = rport;
6481 + conn->ripaddr[0] = ripaddr[0];
6482 + conn->ripaddr[1] = ripaddr[1];
6483 +
6484 + return conn;
6485 +}
6486 +#endif /* UIP_ACTIVE_OPEN */
6487 +/*-----------------------------------------------------------------------------------*/
6488 +#if UIP_UDP
6489 +struct uip_udp_conn *
6490 +uip_udp_new(unsigned short int *ripaddr, unsigned short int rport)
6491 +{
6492 + register struct uip_udp_conn *conn;
6493 +
6494 + /* Find an unused local port. */
6495 + again:
6496 + ++lastport;
6497 +
6498 + if(lastport >= 32000) {
6499 + lastport = 4096;
6500 + }
6501 +
6502 + for(c = 0; c < UIP_UDP_CONNS; ++c) {
6503 + if(uip_udp_conns[c].lport == lastport) {
6504 + goto again;
6505 + }
6506 + }
6507 +
6508 +
6509 + conn = 0;
6510 + for(c = 0; c < UIP_UDP_CONNS; ++c) {
6511 + if(uip_udp_conns[c].lport == 0) {
6512 + conn = &uip_udp_conns[c];
6513 + break;
6514 + }
6515 + }
6516 +
6517 + if(conn == 0) {
6518 + return 0;
6519 + }
6520 +
6521 + conn->lport = HTONS(lastport);
6522 + conn->rport = HTONS(rport);
6523 + conn->ripaddr[0] = ripaddr[0];
6524 + conn->ripaddr[1] = ripaddr[1];
6525 +
6526 + return conn;
6527 +}
6528 +#endif /* UIP_UDP */
6529 +/*-----------------------------------------------------------------------------------*/
6530 +void
6531 +uip_unlisten(unsigned short int port)
6532 +{
6533 + for(c = 0; c < UIP_LISTENPORTS; ++c) {
6534 + if(uip_listenports[c] == port) {
6535 + uip_listenports[c] = 0;
6536 + return;
6537 + }
6538 + }
6539 +}
6540 +/*-----------------------------------------------------------------------------------*/
6541 +void
6542 +uip_listen(unsigned short int port)
6543 +{
6544 + for(c = 0; c < UIP_LISTENPORTS; ++c) {
6545 + if(uip_listenports[c] == 0) {
6546 + uip_listenports[c] = port;
6547 + return;
6548 + }
6549 + }
6550 +}
6551 +/*-----------------------------------------------------------------------------------*/
6552 +/* XXX: IP fragment reassembly: not well-tested. */
6553 +
6554 +#if UIP_REASSEMBLY
6555 +#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
6556 +static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
6557 +static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
6558 +static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
6559 + 0x0f, 0x07, 0x03, 0x01};
6560 +static unsigned short int uip_reasslen;
6561 +static u8_t uip_reassflags;
6562 +#define UIP_REASS_FLAG_LASTFRAG 0x01
6563 +static u8_t uip_reasstmr;
6564 +
6565 +#define IP_HLEN 20
6566 +#define IP_MF 0x20
6567 +
6568 +static u8_t
6569 +uip_reass(void)
6570 +{
6571 + unsigned short int offset, len;
6572 + unsigned short int i;
6573 +
6574 + /* If ip_reasstmr is zero, no packet is present in the buffer, so we
6575 + write the IP header of the fragment into the reassembly
6576 + buffer. The timer is updated with the maximum age. */
6577 + if(uip_reasstmr == 0) {
6578 + memcpy(uip_reassbuf, &BUF->vhl, IP_HLEN);
6579 + uip_reasstmr = UIP_REASS_MAXAGE;
6580 + uip_reassflags = 0;
6581 + /* Clear the bitmap. */
6582 + memset(uip_reassbitmap, sizeof(uip_reassbitmap), 0);
6583 + }
6584 +
6585 + /* Check if the incoming fragment matches the one currently present
6586 + in the reasembly buffer. If so, we proceed with copying the
6587 + fragment into the buffer. */
6588 + if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
6589 + BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
6590 + BUF->destipaddr[0] == FBUF->destipaddr[0] &&
6591 + BUF->destipaddr[1] == FBUF->destipaddr[1] &&
6592 + BUF->ipid[0] == FBUF->ipid[0] &&
6593 + BUF->ipid[1] == FBUF->ipid[1]) {
6594 +
6595 + len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
6596 + offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
6597 +
6598 + /* If the offset or the offset + fragment length overflows the
6599 + reassembly buffer, we discard the entire packet. */
6600 + if(offset > UIP_REASS_BUFSIZE ||
6601 + offset + len > UIP_REASS_BUFSIZE) {
6602 + uip_reasstmr = 0;
6603 + goto nullreturn;
6604 + }
6605 +
6606 + /* Copy the fragment into the reassembly buffer, at the right
6607 + offset. */
6608 + memcpy(&uip_reassbuf[IP_HLEN + offset],
6609 + (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
6610 + len);
6611 +
6612 + /* Update the bitmap. */
6613 + if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
6614 + /* If the two endpoints are in the same byte, we only update
6615 + that byte. */
6616 +
6617 + uip_reassbitmap[offset / (8 * 8)] |=
6618 + bitmap_bits[(offset / 8 ) & 7] &
6619 + ~bitmap_bits[((offset + len) / 8 ) & 7];
6620 + } else {
6621 + /* If the two endpoints are in different bytes, we update the
6622 + bytes in the endpoints and fill the stuff inbetween with
6623 + 0xff. */
6624 + uip_reassbitmap[offset / (8 * 8)] |=
6625 + bitmap_bits[(offset / 8 ) & 7];
6626 + for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
6627 + uip_reassbitmap[i] = 0xff;
6628 + }
6629 + uip_reassbitmap[(offset + len) / (8 * 8)] |=
6630 + ~bitmap_bits[((offset + len) / 8 ) & 7];
6631 + }
6632 +
6633 + /* If this fragment has the More Fragments flag set to zero, we
6634 + know that this is the last fragment, so we can calculate the
6635 + size of the entire packet. We also set the
6636 + IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
6637 + the final fragment. */
6638 +
6639 + if((BUF->ipoffset[0] & IP_MF) == 0) {
6640 + uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
6641 + uip_reasslen = offset + len;
6642 + }
6643 +
6644 + /* Finally, we check if we have a full packet in the buffer. We do
6645 + this by checking if we have the last fragment and if all bits
6646 + in the bitmap are set. */
6647 + if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
6648 + /* Check all bytes up to and including all but the last byte in
6649 + the bitmap. */
6650 + for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
6651 + if(uip_reassbitmap[i] != 0xff) {
6652 + goto nullreturn;
6653 + }
6654 + }
6655 + /* Check the last byte in the bitmap. It should contain just the
6656 + right amount of bits. */
6657 + if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
6658 + (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
6659 + goto nullreturn;
6660 + }
6661 +
6662 + /* If we have come this far, we have a full packet in the
6663 + buffer, so we allocate a pbuf and copy the packet into it. We
6664 + also reset the timer. */
6665 + uip_reasstmr = 0;
6666 + memcpy(BUF, FBUF, uip_reasslen);
6667 +
6668 + /* Pretend to be a "normal" (i.e., not fragmented) IP packet
6669 + from now on. */
6670 + BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
6671 + BUF->len[0] = uip_reasslen >> 8;
6672 + BUF->len[1] = uip_reasslen & 0xff;
6673 + BUF->ipchksum = 0;
6674 + BUF->ipchksum = ~(uip_ipchksum());
6675 +
6676 + return uip_reasslen;
6677 + }
6678 + }
6679 +
6680 + nullreturn:
6681 + return 0;
6682 +}
6683 +#endif /* UIP_REASSEMBL */
6684 +/*-----------------------------------------------------------------------------------*/
6685 +static void
6686 +uip_add_rcv_nxt(unsigned short int n)
6687 +{
6688 + uip_add32(uip_conn->rcv_nxt, n);
6689 + uip_conn->rcv_nxt[0] = uip_acc32[0];
6690 + uip_conn->rcv_nxt[1] = uip_acc32[1];
6691 + uip_conn->rcv_nxt[2] = uip_acc32[2];
6692 + uip_conn->rcv_nxt[3] = uip_acc32[3];
6693 +}
6694 +/*-----------------------------------------------------------------------------------*/
6695 +void
6696 +uip_process(u8_t flag)
6697 +{
6698 + register struct uip_conn *uip_connr = uip_conn;
6699 +
6700 + uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
6701 +
6702 +
6703 + /* Check if we were invoked because of the perodic timer fireing. */
6704 + if(flag == UIP_TIMER) {
6705 +#if UIP_REASSEMBLY
6706 + if(uip_reasstmr != 0) {
6707 + --uip_reasstmr;
6708 + }
6709 +#endif /* UIP_REASSEMBLY */
6710 + /* Increase the initial sequence number. */
6711 + if(++iss[3] == 0) {
6712 + if(++iss[2] == 0) {
6713 + if(++iss[1] == 0) {
6714 + ++iss[0];
6715 + }
6716 + }
6717 + }
6718 + uip_len = 0;
6719 + if(uip_connr->tcpstateflags == TIME_WAIT ||
6720 + uip_connr->tcpstateflags == FIN_WAIT_2) {
6721 + ++(uip_connr->timer);
6722 + if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
6723 + uip_connr->tcpstateflags = CLOSED;
6724 + }
6725 + } else if(uip_connr->tcpstateflags != CLOSED) {
6726 + /* If the connection has outstanding data, we increase the
6727 + connection's timer and see if it has reached the RTO value
6728 + in which case we retransmit. */
6729 + if(uip_outstanding(uip_connr)) {
6730 + if(uip_connr->timer-- == 0) {
6731 + if(uip_connr->nrtx == UIP_MAXRTX ||
6732 + ((uip_connr->tcpstateflags == SYN_SENT ||
6733 + uip_connr->tcpstateflags == SYN_RCVD) &&
6734 + uip_connr->nrtx == UIP_MAXSYNRTX)) {
6735 + uip_connr->tcpstateflags = CLOSED;
6736 +
6737 + /* We call UIP_APPCALL() with uip_flags set to
6738 + UIP_TIMEDOUT to inform the application that the
6739 + connection has timed out. */
6740 + uip_flags = UIP_TIMEDOUT;
6741 + UIP_APPCALL();
6742 +
6743 + /* We also send a reset packet to the remote host. */
6744 + BUF->flags = TCP_RST | TCP_ACK;
6745 + goto tcp_send_nodata;
6746 + }
6747 +
6748 + /* Exponential backoff. */
6749 + uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
6750 + 4:
6751 + uip_connr->nrtx);
6752 + ++(uip_connr->nrtx);
6753 +
6754 + /* Ok, so we need to retransmit. We do this differently
6755 + depending on which state we are in. In ESTABLISHED, we
6756 + call upon the application so that it may prepare the
6757 + data for the retransmit. In SYN_RCVD, we resend the
6758 + SYNACK that we sent earlier and in LAST_ACK we have to
6759 + retransmit our FINACK. */
6760 + UIP_STAT(++uip_stat.tcp.rexmit);
6761 + switch(uip_connr->tcpstateflags & TS_MASK) {
6762 + case SYN_RCVD:
6763 + /* In the SYN_RCVD state, we should retransmit our
6764 + SYNACK. */
6765 + goto tcp_send_synack;
6766 +
6767 +#if UIP_ACTIVE_OPEN
6768 + case SYN_SENT:
6769 + /* In the SYN_SENT state, we retransmit out SYN. */
6770 + BUF->flags = 0;
6771 + goto tcp_send_syn;
6772 +#endif /* UIP_ACTIVE_OPEN */
6773 +
6774 + case ESTABLISHED:
6775 + /* In the ESTABLISHED state, we call upon the application
6776 + to do the actual retransmit after which we jump into
6777 + the code for sending out the packet (the apprexmit
6778 + label). */
6779 + uip_len = 0;
6780 + uip_slen = 0;
6781 + uip_flags = UIP_REXMIT;
6782 + UIP_APPCALL();
6783 + goto apprexmit;
6784 +
6785 + case FIN_WAIT_1:
6786 + case CLOSING:
6787 + case LAST_ACK:
6788 + /* In all these states we should retransmit a FINACK. */
6789 + goto tcp_send_finack;
6790 +
6791 + }
6792 + }
6793 + } else if((uip_connr->tcpstateflags & TS_MASK) == ESTABLISHED) {
6794 + /* If there was no need for a retransmission, we poll the
6795 + application for new data. */
6796 + uip_len = 0;
6797 + uip_slen = 0;
6798 + uip_flags = UIP_POLL;
6799 + UIP_APPCALL();
6800 + goto appsend;
6801 + }
6802 + }
6803 + goto drop;
6804 + }
6805 +#if UIP_UDP
6806 + if(flag == UIP_UDP_TIMER) {
6807 + if(uip_udp_conn->lport != 0) {
6808 + uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
6809 + uip_len = uip_slen = 0;
6810 + uip_flags = UIP_POLL;
6811 + UIP_UDP_APPCALL();
6812 + goto udp_send;
6813 + } else {
6814 + goto drop;
6815 + }
6816 + }
6817 +#endif
6818 +
6819 + /* This is where the input processing starts. */
6820 + UIP_STAT(++uip_stat.ip.recv);
6821 +
6822 +
6823 + /* Start of IPv4 input header processing code. */
6824 +
6825 + /* Check validity of the IP header. */
6826 + if(BUF->vhl != 0x45) { /* IP version and header length. */
6827 + UIP_STAT(++uip_stat.ip.drop);
6828 + UIP_STAT(++uip_stat.ip.vhlerr);
6829 + UIP_LOG("ip: invalid version or header length.");
6830 + goto drop;
6831 + }
6832 +
6833 + /* Check the size of the packet. If the size reported to us in
6834 + uip_len doesn't match the size reported in the IP header, there
6835 + has been a transmission error and we drop the packet. */
6836 +
6837 + if(BUF->len[0] != (uip_len >> 8)) { /* IP length, high byte. */
6838 + uip_len = (uip_len & 0xff) | (BUF->len[0] << 8);
6839 + }
6840 + if(BUF->len[1] != (uip_len & 0xff)) { /* IP length, low byte. */
6841 + uip_len = (uip_len & 0xff00) | BUF->len[1];
6842 + }
6843 +
6844 + /* Check the fragment flag. */
6845 + if((BUF->ipoffset[0] & 0x3f) != 0 ||
6846 + BUF->ipoffset[1] != 0) {
6847 +#if UIP_REASSEMBLY
6848 + uip_len = uip_reass();
6849 + if(uip_len == 0) {
6850 + goto drop;
6851 + }
6852 +#else
6853 + UIP_STAT(++uip_stat.ip.drop);
6854 + UIP_STAT(++uip_stat.ip.fragerr);
6855 + UIP_LOG("ip: fragment dropped.");
6856 + goto drop;
6857 +#endif /* UIP_REASSEMBLY */
6858 + }
6859 +
6860 + /* If we are configured to use ping IP address configuration and
6861 + hasn't been assigned an IP address yet, we accept all ICMP
6862 + packets. */
6863 +#if UIP_PINGADDRCONF
6864 + if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
6865 + if(BUF->proto == UIP_PROTO_ICMP) {
6866 + UIP_LOG("ip: possible ping config packet received.");
6867 + goto icmp_input;
6868 + } else {
6869 + UIP_LOG("ip: packet dropped since no address assigned.");
6870 + goto drop;
6871 + }
6872 + }
6873 +#endif /* UIP_PINGADDRCONF */
6874 +
6875 + /* Check if the packet is destined for our IP address. */
6876 + if(BUF->destipaddr[0] != uip_hostaddr[0]) {
6877 + UIP_STAT(++uip_stat.ip.drop);
6878 + UIP_LOG("ip: packet not for us.");
6879 + goto drop;
6880 + }
6881 + if(BUF->destipaddr[1] != uip_hostaddr[1]) {
6882 + UIP_STAT(++uip_stat.ip.drop);
6883 + UIP_LOG("ip: packet not for us.");
6884 + goto drop;
6885 + }
6886 +
6887 + if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
6888 + checksum. */
6889 + UIP_STAT(++uip_stat.ip.drop);
6890 + UIP_STAT(++uip_stat.ip.chkerr);
6891 + UIP_LOG("ip: bad checksum.");
6892 + goto drop;
6893 + }
6894 +
6895 + if(BUF->proto == UIP_PROTO_TCP) /* Check for TCP packet. If so, jump
6896 + to the tcp_input label. */
6897 + goto tcp_input;
6898 +
6899 +#if UIP_UDP
6900 + if(BUF->proto == UIP_PROTO_UDP)
6901 + goto udp_input;
6902 +#endif /* UIP_UDP */
6903 +
6904 + if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
6905 + here. */
6906 + UIP_STAT(++uip_stat.ip.drop);
6907 + UIP_STAT(++uip_stat.ip.protoerr);
6908 + UIP_LOG("ip: neither tcp nor icmp.");
6909 + goto drop;
6910 + }
6911 +
6912 + //icmp_input:
6913 + UIP_STAT(++uip_stat.icmp.recv);
6914 +
6915 + /* ICMP echo (i.e., ping) processing. This is simple, we only change
6916 + the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
6917 + checksum before we return the packet. */
6918 + if(ICMPBUF->type != ICMP_ECHO) {
6919 + UIP_STAT(++uip_stat.icmp.drop);
6920 + UIP_STAT(++uip_stat.icmp.typeerr);
6921 + UIP_LOG("icmp: not icmp echo.");
6922 + goto drop;
6923 + }
6924 +
6925 + /* If we are configured to use ping IP address assignment, we use
6926 + the destination IP address of this ping packet and assign it to
6927 + ourself. */
6928 +#if UIP_PINGADDRCONF
6929 + if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
6930 + uip_hostaddr[0] = BUF->destipaddr[0];
6931 + uip_hostaddr[1] = BUF->destipaddr[1];
6932 + }
6933 +#endif /* UIP_PINGADDRCONF */
6934 +
6935 + ICMPBUF->type = ICMP_ECHO_REPLY;
6936 +
6937 + if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
6938 + ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
6939 + } else {
6940 + ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
6941 + }
6942 +
6943 + /* Swap IP addresses. */
6944 + tmp16 = BUF->destipaddr[0];
6945 + BUF->destipaddr[0] = BUF->srcipaddr[0];
6946 + BUF->srcipaddr[0] = tmp16;
6947 + tmp16 = BUF->destipaddr[1];
6948 + BUF->destipaddr[1] = BUF->srcipaddr[1];
6949 + BUF->srcipaddr[1] = tmp16;
6950 +
6951 + UIP_STAT(++uip_stat.icmp.sent);
6952 + goto send;
6953 +
6954 + /* End of IPv4 input header processing code. */
6955 +
6956 +
6957 +#if UIP_UDP
6958 + /* UDP input processing. */
6959 + udp_input:
6960 + /* UDP processing is really just a hack. We don't do anything to the
6961 + UDP/IP headers, but let the UDP application do all the hard
6962 + work. If the application sets uip_slen, it has a packet to
6963 + send. */
6964 +#if UIP_UDP_CHECKSUMS
6965 + if(uip_udpchksum() != 0xffff) {
6966 + UIP_STAT(++uip_stat.udp.drop);
6967 + UIP_STAT(++uip_stat.udp.chkerr);
6968 + UIP_LOG("udp: bad checksum.");
6969 + goto drop;
6970 + }
6971 +#endif /* UIP_UDP_CHECKSUMS */
6972 +
6973 + /* Demultiplex this UDP packet between the UDP "connections". */
6974 + for(uip_udp_conn = &uip_udp_conns[0];
6975 + uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
6976 + ++uip_udp_conn) {
6977 + if(uip_udp_conn->lport != 0 &&
6978 + UDPBUF->destport == uip_udp_conn->lport &&
6979 + (uip_udp_conn->rport == 0 ||
6980 + UDPBUF->srcport == uip_udp_conn->rport) &&
6981 + BUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] &&
6982 + BUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) {
6983 + goto udp_found;
6984 + }
6985 + }
6986 + goto drop;
6987 +
6988 + udp_found:
6989 + uip_len = uip_len - 28;
6990 + uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
6991 + uip_flags = UIP_NEWDATA;
6992 + uip_slen = 0;
6993 + UIP_UDP_APPCALL();
6994 + udp_send:
6995 + if(uip_slen == 0) {
6996 + goto drop;
6997 + }
6998 + uip_len = uip_slen + 28;
6999 +
7000 + BUF->len[0] = (uip_len >> 8);
7001 + BUF->len[1] = (uip_len & 0xff);
7002 +
7003 + BUF->proto = UIP_PROTO_UDP;
7004 +
7005 + UDPBUF->udplen = HTONS(uip_slen + 8);
7006 + UDPBUF->udpchksum = 0;
7007 +#if UIP_UDP_CHECKSUMS
7008 + /* Calculate UDP checksum. */
7009 + UDPBUF->udpchksum = ~(uip_udpchksum());
7010 + if(UDPBUF->udpchksum == 0) {
7011 + UDPBUF->udpchksum = 0xffff;
7012 + }
7013 +#endif /* UIP_UDP_CHECKSUMS */
7014 +
7015 + BUF->srcport = uip_udp_conn->lport;
7016 + BUF->destport = uip_udp_conn->rport;
7017 +
7018 + BUF->srcipaddr[0] = uip_hostaddr[0];
7019 + BUF->srcipaddr[1] = uip_hostaddr[1];
7020 + BUF->destipaddr[0] = uip_udp_conn->ripaddr[0];
7021 + BUF->destipaddr[1] = uip_udp_conn->ripaddr[1];
7022 +
7023 + uip_appdata = &uip_buf[UIP_LLH_LEN + 40];
7024 + goto ip_send_nolen;
7025 +#endif /* UIP_UDP */
7026 +
7027 + /* TCP input processing. */
7028 + tcp_input:
7029 + UIP_STAT(++uip_stat.tcp.recv);
7030 +
7031 + /* Start of TCP input header processing code. */
7032 +
7033 + if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
7034 + checksum. */
7035 + UIP_STAT(++uip_stat.tcp.drop);
7036 + UIP_STAT(++uip_stat.tcp.chkerr);
7037 + UIP_LOG("tcp: bad checksum.");
7038 + goto drop;
7039 + }
7040 +
7041 + /* Demultiplex this segment. */
7042 + /* First check any active connections. */
7043 + for(uip_connr = &uip_conns[0]; uip_connr < &uip_conns[UIP_CONNS]; ++uip_connr) {
7044 + if(uip_connr->tcpstateflags != CLOSED &&
7045 + BUF->destport == uip_connr->lport &&
7046 + BUF->srcport == uip_connr->rport &&
7047 + BUF->srcipaddr[0] == uip_connr->ripaddr[0] &&
7048 + BUF->srcipaddr[1] == uip_connr->ripaddr[1]) {
7049 + goto found;
7050 + }
7051 + }
7052 +
7053 + /* If we didn't find and active connection that expected the packet,
7054 + either this packet is an old duplicate, or this is a SYN packet
7055 + destined for a connection in LISTEN. If the SYN flag isn't set,
7056 + it is an old packet and we send a RST. */
7057 + if((BUF->flags & TCP_CTL) != TCP_SYN)
7058 + goto reset;
7059 +
7060 + tmp16 = BUF->destport;
7061 + /* Next, check listening connections. */
7062 + for(c = 0; c < UIP_LISTENPORTS; ++c) {
7063 + if(tmp16 == uip_listenports[c])
7064 + goto found_listen;
7065 + }
7066 +
7067 + /* No matching connection found, so we send a RST packet. */
7068 + UIP_STAT(++uip_stat.tcp.synrst);
7069 + reset:
7070 +
7071 + /* We do not send resets in response to resets. */
7072 + if(BUF->flags & TCP_RST)
7073 + goto drop;
7074 +
7075 + UIP_STAT(++uip_stat.tcp.rst);
7076 +
7077 + BUF->flags = TCP_RST | TCP_ACK;
7078 + uip_len = 40;
7079 + BUF->tcpoffset = 5 << 4;
7080 +
7081 + /* Flip the seqno and ackno fields in the TCP header. */
7082 + c = BUF->seqno[3];
7083 + BUF->seqno[3] = BUF->ackno[3];
7084 + BUF->ackno[3] = c;
7085 +
7086 + c = BUF->seqno[2];
7087 + BUF->seqno[2] = BUF->ackno[2];
7088 + BUF->ackno[2] = c;
7089 +
7090 + c = BUF->seqno[1];
7091 + BUF->seqno[1] = BUF->ackno[1];
7092 + BUF->ackno[1] = c;
7093 +
7094 + c = BUF->seqno[0];
7095 + BUF->seqno[0] = BUF->ackno[0];
7096 + BUF->ackno[0] = c;
7097 +
7098 + /* We also have to increase the sequence number we are
7099 + acknowledging. If the least significant byte overflowed, we need
7100 + to propagate the carry to the other bytes as well. */
7101 + if(++BUF->ackno[3] == 0) {
7102 + if(++BUF->ackno[2] == 0) {
7103 + if(++BUF->ackno[1] == 0) {
7104 + ++BUF->ackno[0];
7105 + }
7106 + }
7107 + }
7108 +
7109 + /* Swap port numbers. */
7110 + tmp16 = BUF->srcport;
7111 + BUF->srcport = BUF->destport;
7112 + BUF->destport = tmp16;
7113 +
7114 + /* Swap IP addresses. */
7115 + tmp16 = BUF->destipaddr[0];
7116 + BUF->destipaddr[0] = BUF->srcipaddr[0];
7117 + BUF->srcipaddr[0] = tmp16;
7118 + tmp16 = BUF->destipaddr[1];
7119 + BUF->destipaddr[1] = BUF->srcipaddr[1];
7120 + BUF->srcipaddr[1] = tmp16;
7121 +
7122 +
7123 + /* And send out the RST packet! */
7124 + goto tcp_send_noconn;
7125 +
7126 + /* This label will be jumped to if we matched the incoming packet
7127 + with a connection in LISTEN. In that case, we should create a new
7128 + connection and send a SYNACK in return. */
7129 + found_listen:
7130 + /* First we check if there are any connections avaliable. Unused
7131 + connections are kept in the same table as used connections, but
7132 + unused ones have the tcpstate set to CLOSED. Also, connections in
7133 + TIME_WAIT are kept track of and we'll use the oldest one if no
7134 + CLOSED connections are found. Thanks to Eddie C. Dost for a very
7135 + nice algorithm for the TIME_WAIT search. */
7136 + uip_connr = 0;
7137 + for(c = 0; c < UIP_CONNS; ++c) {
7138 + if(uip_conns[c].tcpstateflags == CLOSED) {
7139 + uip_connr = &uip_conns[c];
7140 + break;
7141 + }
7142 + if(uip_conns[c].tcpstateflags == TIME_WAIT) {
7143 + if(uip_connr == 0 ||
7144 + uip_conns[c].timer > uip_connr->timer) {
7145 + uip_connr = &uip_conns[c];
7146 + }
7147 + }
7148 + }
7149 +
7150 + if(uip_connr == 0) {
7151 + /* All connections are used already, we drop packet and hope that
7152 + the remote end will retransmit the packet at a time when we
7153 + have more spare connections. */
7154 + UIP_STAT(++uip_stat.tcp.syndrop);
7155 + UIP_LOG("tcp: found no unused connections.");
7156 + goto drop;
7157 + }
7158 + uip_conn = uip_connr;
7159 +
7160 + /* Fill in the necessary fields for the new connection. */
7161 + uip_connr->rto = uip_connr->timer = UIP_RTO;
7162 + uip_connr->sa = 0;
7163 + uip_connr->sv = 4;
7164 + uip_connr->nrtx = 0;
7165 + uip_connr->lport = BUF->destport;
7166 + uip_connr->rport = BUF->srcport;
7167 + uip_connr->ripaddr[0] = BUF->srcipaddr[0];
7168 + uip_connr->ripaddr[1] = BUF->srcipaddr[1];
7169 + uip_connr->tcpstateflags = SYN_RCVD;
7170 +
7171 + uip_connr->snd_nxt[0] = iss[0];
7172 + uip_connr->snd_nxt[1] = iss[1];
7173 + uip_connr->snd_nxt[2] = iss[2];
7174 + uip_connr->snd_nxt[3] = iss[3];
7175 + uip_connr->len = 1;
7176 +
7177 + /* rcv_nxt should be the seqno from the incoming packet + 1. */
7178 + uip_connr->rcv_nxt[3] = BUF->seqno[3];
7179 + uip_connr->rcv_nxt[2] = BUF->seqno[2];
7180 + uip_connr->rcv_nxt[1] = BUF->seqno[1];
7181 + uip_connr->rcv_nxt[0] = BUF->seqno[0];
7182 + uip_add_rcv_nxt(1);
7183 +
7184 + /* Parse the TCP MSS option, if present. */
7185 + if((BUF->tcpoffset & 0xf0) > 0x50) {
7186 + for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
7187 + opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
7188 + if(opt == 0x00) {
7189 + /* End of options. */
7190 + break;
7191 + } else if(opt == 0x01) {
7192 + ++c;
7193 + /* NOP option. */
7194 + } else if(opt == 0x02 &&
7195 + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
7196 + /* An MSS option with the right option length. */
7197 + tmp16 = ((unsigned short int)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
7198 + (unsigned short int)uip_buf[40 + UIP_LLH_LEN + 3 + c];
7199 + uip_connr->initialmss = uip_connr->mss =
7200 + tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
7201 +
7202 + /* And we are done processing options. */
7203 + break;
7204 + } else {
7205 + /* All other options have a length field, so that we easily
7206 + can skip past them. */
7207 + if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
7208 + /* If the length field is zero, the options are malformed
7209 + and we don't process them further. */
7210 + break;
7211 + }
7212 + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
7213 + }
7214 + }
7215 + }
7216 +
7217 + /* Our response will be a SYNACK. */
7218 +#if UIP_ACTIVE_OPEN
7219 + tcp_send_synack:
7220 + BUF->flags = TCP_ACK;
7221 +
7222 + tcp_send_syn:
7223 + BUF->flags |= TCP_SYN;
7224 +#else /* UIP_ACTIVE_OPEN */
7225 + tcp_send_synack:
7226 + BUF->flags = TCP_SYN | TCP_ACK;
7227 +#endif /* UIP_ACTIVE_OPEN */
7228 +
7229 + /* We send out the TCP Maximum Segment Size option with our
7230 + SYNACK. */
7231 + BUF->optdata[0] = 2;
7232 + BUF->optdata[1] = 4;
7233 + BUF->optdata[2] = (UIP_TCP_MSS) / 256;
7234 + BUF->optdata[3] = (UIP_TCP_MSS) & 255;
7235 + uip_len = 44;
7236 + BUF->tcpoffset = 6 << 4;
7237 + goto tcp_send;
7238 +
7239 + /* This label will be jumped to if we found an active connection. */
7240 + found:
7241 + uip_conn = uip_connr;
7242 + uip_flags = 0;
7243 +
7244 + /* We do a very naive form of TCP reset processing; we just accept
7245 + any RST and kill our connection. We should in fact check if the
7246 + sequence number of this reset is wihtin our advertised window
7247 + before we accept the reset. */
7248 + if(BUF->flags & TCP_RST) {
7249 + uip_connr->tcpstateflags = CLOSED;
7250 + UIP_LOG("tcp: got reset, aborting connection.");
7251 + uip_flags = UIP_ABORT;
7252 + UIP_APPCALL();
7253 + goto drop;
7254 + }
7255 + /* Calculated the length of the data, if the application has sent
7256 + any data to us. */
7257 + c = (BUF->tcpoffset >> 4) << 2;
7258 + /* uip_len will contain the length of the actual TCP data. This is
7259 + calculated by subtracing the length of the TCP header (in
7260 + c) and the length of the IP header (20 bytes). */
7261 + uip_len = uip_len - c - 20;
7262 +
7263 + /* First, check if the sequence number of the incoming packet is
7264 + what we're expecting next. If not, we send out an ACK with the
7265 + correct numbers in. */
7266 + if(uip_len > 0 &&
7267 + (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
7268 + BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
7269 + BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
7270 + BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
7271 + goto tcp_send_ack;
7272 + }
7273 +
7274 + /* Next, check if the incoming segment acknowledges any outstanding
7275 + data. If so, we update the sequence number, reset the length of
7276 + the outstanding data, calculate RTT estimations, and reset the
7277 + retransmission timer. */
7278 + if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
7279 + uip_add32(uip_connr->snd_nxt, uip_connr->len);
7280 + if(BUF->ackno[0] == uip_acc32[0] &&
7281 + BUF->ackno[1] == uip_acc32[1] &&
7282 + BUF->ackno[2] == uip_acc32[2] &&
7283 + BUF->ackno[3] == uip_acc32[3]) {
7284 + /* Update sequence number. */
7285 + uip_connr->snd_nxt[0] = uip_acc32[0];
7286 + uip_connr->snd_nxt[1] = uip_acc32[1];
7287 + uip_connr->snd_nxt[2] = uip_acc32[2];
7288 + uip_connr->snd_nxt[3] = uip_acc32[3];
7289 +
7290 +
7291 + /* Do RTT estimation, unless we have done retransmissions. */
7292 + if(uip_connr->nrtx == 0) {
7293 + signed char m;
7294 + m = uip_connr->rto - uip_connr->timer;
7295 + /* This is taken directly from VJs original code in his paper */
7296 + m = m - (uip_connr->sa >> 3);
7297 + uip_connr->sa += m;
7298 + if(m < 0) {
7299 + m = -m;
7300 + }
7301 + m = m - (uip_connr->sv >> 2);
7302 + uip_connr->sv += m;
7303 + uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
7304 +
7305 + }
7306 + /* Set the acknowledged flag. */
7307 + uip_flags = UIP_ACKDATA;
7308 + /* Reset the retransmission timer. */
7309 + uip_connr->timer = uip_connr->rto;
7310 + }
7311 +
7312 + }
7313 +
7314 + /* Do different things depending on in what state the connection is. */
7315 + switch(uip_connr->tcpstateflags & TS_MASK) {
7316 + /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
7317 + implemented, since we force the application to close when the
7318 + peer sends a FIN (hence the application goes directly from
7319 + ESTABLISHED to LAST_ACK). */
7320 + case SYN_RCVD:
7321 + /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
7322 + we are waiting for an ACK that acknowledges the data we sent
7323 + out the last time. Therefore, we want to have the UIP_ACKDATA
7324 + flag set. If so, we enter the ESTABLISHED state. */
7325 + if(uip_flags & UIP_ACKDATA) {
7326 + uip_connr->tcpstateflags = ESTABLISHED;
7327 + uip_flags = UIP_CONNECTED;
7328 + uip_connr->len = 0;
7329 + if(uip_len > 0) {
7330 + uip_flags |= UIP_NEWDATA;
7331 + uip_add_rcv_nxt(uip_len);
7332 + }
7333 + uip_slen = 0;
7334 + UIP_APPCALL();
7335 + goto appsend;
7336 + }
7337 + goto drop;
7338 +#if UIP_ACTIVE_OPEN
7339 + case SYN_SENT:
7340 + /* In SYN_SENT, we wait for a SYNACK that is sent in response to
7341 + our SYN. The rcv_nxt is set to sequence number in the SYNACK
7342 + plus one, and we send an ACK. We move into the ESTABLISHED
7343 + state. */
7344 + if((uip_flags & UIP_ACKDATA) &&
7345 + BUF->flags == (TCP_SYN | TCP_ACK)) {
7346 +
7347 + /* Parse the TCP MSS option, if present. */
7348 + if((BUF->tcpoffset & 0xf0) > 0x50) {
7349 + for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
7350 + opt = uip_buf[40 + UIP_LLH_LEN + c];
7351 + if(opt == 0x00) {
7352 + /* End of options. */
7353 + break;
7354 + } else if(opt == 0x01) {
7355 + ++c;
7356 + /* NOP option. */
7357 + } else if(opt == 0x02 &&
7358 + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
7359 + /* An MSS option with the right option length. */
7360 + tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
7361 + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
7362 + uip_connr->initialmss =
7363 + uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
7364 +
7365 + /* And we are done processing options. */
7366 + break;
7367 + } else {
7368 + /* All other options have a length field, so that we easily
7369 + can skip past them. */
7370 + if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
7371 + /* If the length field is zero, the options are malformed
7372 + and we don't process them further. */
7373 + break;
7374 + }
7375 + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
7376 + }
7377 + }
7378 + }
7379 + uip_connr->tcpstateflags = ESTABLISHED;
7380 + uip_connr->rcv_nxt[0] = BUF->seqno[0];
7381 + uip_connr->rcv_nxt[1] = BUF->seqno[1];
7382 + uip_connr->rcv_nxt[2] = BUF->seqno[2];
7383 + uip_connr->rcv_nxt[3] = BUF->seqno[3];
7384 + uip_add_rcv_nxt(1);
7385 + uip_flags = UIP_CONNECTED | UIP_NEWDATA;
7386 + uip_connr->len = 0;
7387 + uip_len = 0;
7388 + uip_slen = 0;
7389 + UIP_APPCALL();
7390 + goto appsend;
7391 + }
7392 + goto reset;
7393 +#endif /* UIP_ACTIVE_OPEN */
7394 +
7395 + case ESTABLISHED:
7396 + /* In the ESTABLISHED state, we call upon the application to feed
7397 + data into the uip_buf. If the UIP_ACKDATA flag is set, the
7398 + application should put new data into the buffer, otherwise we are
7399 + retransmitting an old segment, and the application should put that
7400 + data into the buffer.
7401 +
7402 + If the incoming packet is a FIN, we should close the connection on
7403 + this side as well, and we send out a FIN and enter the LAST_ACK
7404 + state. We require that there is no outstanding data; otherwise the
7405 + sequence numbers will be screwed up. */
7406 +
7407 + if(BUF->flags & TCP_FIN) {
7408 + if(uip_outstanding(uip_connr)) {
7409 + goto drop;
7410 + }
7411 + uip_add_rcv_nxt(1 + uip_len);
7412 + uip_flags = UIP_CLOSE;
7413 + if(uip_len > 0) {
7414 + uip_flags |= UIP_NEWDATA;
7415 + }
7416 + UIP_APPCALL();
7417 + uip_connr->len = 1;
7418 + uip_connr->tcpstateflags = LAST_ACK;
7419 + uip_connr->nrtx = 0;
7420 + tcp_send_finack:
7421 + BUF->flags = TCP_FIN | TCP_ACK;
7422 + goto tcp_send_nodata;
7423 + }
7424 +
7425 + /* Check the URG flag. If this is set, the segment carries urgent
7426 + data that we must pass to the application. */
7427 + if(BUF->flags & TCP_URG) {
7428 +#if UIP_URGDATA > 0
7429 + uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
7430 + if(uip_urglen > uip_len) {
7431 + /* There is more urgent data in the next segment to come. */
7432 + uip_urglen = uip_len;
7433 + }
7434 + uip_add_rcv_nxt(uip_urglen);
7435 + uip_len -= uip_urglen;
7436 + uip_urgdata = uip_appdata;
7437 + uip_appdata += uip_urglen;
7438 + } else {
7439 + uip_urglen = 0;
7440 +#endif /* UIP_URGDATA > 0 */
7441 + uip_appdata += (BUF->urgp[0] << 8) | BUF->urgp[1];
7442 + uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
7443 + }
7444 +
7445 +
7446 + /* If uip_len > 0 we have TCP data in the packet, and we flag this
7447 + by setting the UIP_NEWDATA flag and update the sequence number
7448 + we acknowledge. If the application has stopped the dataflow
7449 + using uip_stop(), we must not accept any data packets from the
7450 + remote host. */
7451 + if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
7452 + uip_flags |= UIP_NEWDATA;
7453 + uip_add_rcv_nxt(uip_len);
7454 + }
7455 +
7456 + /* Check if the available buffer space advertised by the other end
7457 + is smaller than the initial MSS for this connection. If so, we
7458 + set the current MSS to the window size to ensure that the
7459 + application does not send more data than the other end can
7460 + handle.
7461 +
7462 + If the remote host advertises a zero window, we set the MSS to
7463 + the initial MSS so that the application will send an entire MSS
7464 + of data. This data will not be acknowledged by the receiver,
7465 + and the application will retransmit it. This is called the
7466 + "persistent timer" and uses the retransmission mechanim.
7467 + */
7468 + tmp16 = ((unsigned short int)BUF->wnd[0] << 8) + (unsigned short int)BUF->wnd[1];
7469 + if(tmp16 > uip_connr->initialmss ||
7470 + tmp16 == 0) {
7471 + tmp16 = uip_connr->initialmss;
7472 + }
7473 + uip_connr->mss = tmp16;
7474 +
7475 + /* If this packet constitutes an ACK for outstanding data (flagged
7476 + by the UIP_ACKDATA flag, we should call the application since it
7477 + might want to send more data. If the incoming packet had data
7478 + from the peer (as flagged by the UIP_NEWDATA flag), the
7479 + application must also be notified.
7480 +
7481 + When the application is called, the global variable uip_len
7482 + contains the length of the incoming data. The application can
7483 + access the incoming data through the global pointer
7484 + uip_appdata, which usually points 40 bytes into the uip_buf
7485 + array.
7486 +
7487 + If the application wishes to send any data, this data should be
7488 + put into the uip_appdata and the length of the data should be
7489 + put into uip_len. If the application don't have any data to
7490 + send, uip_len must be set to 0. */
7491 + if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
7492 + uip_slen = 0;
7493 + UIP_APPCALL();
7494 +
7495 + appsend:
7496 +
7497 + if(uip_flags & UIP_ABORT) {
7498 + uip_slen = 0;
7499 + uip_connr->tcpstateflags = CLOSED;
7500 + BUF->flags = TCP_RST | TCP_ACK;
7501 + goto tcp_send_nodata;
7502 + }
7503 +
7504 + if(uip_flags & UIP_CLOSE) {
7505 + uip_slen = 0;
7506 + uip_connr->len = 1;
7507 + uip_connr->tcpstateflags = FIN_WAIT_1;
7508 + uip_connr->nrtx = 0;
7509 + BUF->flags = TCP_FIN | TCP_ACK;
7510 + goto tcp_send_nodata;
7511 + }
7512 +
7513 + /* If uip_slen > 0, the application has data to be sent. */
7514 + if(uip_slen > 0) {
7515 +
7516 + /* If the connection has acknowledged data, the contents of
7517 + the ->len variable should be discarded. */
7518 + if((uip_flags & UIP_ACKDATA) != 0) {
7519 + uip_connr->len = 0;
7520 + }
7521 +
7522 + /* If the ->len variable is non-zero the connection has
7523 + already data in transit and cannot send anymore right
7524 + now. */
7525 + if(uip_connr->len == 0) {
7526 +
7527 + /* The application cannot send more than what is allowed by
7528 + the mss (the minumum of the MSS and the available
7529 + window). */
7530 + if(uip_slen > uip_connr->mss) {
7531 + uip_slen = uip_connr->mss;
7532 + }
7533 +
7534 + /* Remember how much data we send out now so that we know
7535 + when everything has been acknowledged. */
7536 + uip_connr->len = uip_slen;
7537 + } else {
7538 +
7539 + /* If the application already had unacknowledged data, we
7540 + make sure that the application does not send (i.e.,
7541 + retransmit) out more than it previously sent out. */
7542 + uip_slen = uip_connr->len;
7543 + }
7544 + } else {
7545 + uip_connr->len = 0;
7546 + }
7547 + uip_connr->nrtx = 0;
7548 + apprexmit:
7549 + uip_appdata = uip_sappdata;
7550 +
7551 + /* If the application has data to be sent, or if the incoming
7552 + packet had new data in it, we must send out a packet. */
7553 + if(uip_slen > 0 && uip_connr->len > 0) {
7554 + /* Add the length of the IP and TCP headers. */
7555 + uip_len = uip_connr->len + UIP_TCPIP_HLEN;
7556 + /* We always set the ACK flag in response packets. */
7557 + BUF->flags = TCP_ACK | TCP_PSH;
7558 + /* Send the packet. */
7559 + goto tcp_send_noopts;
7560 + }
7561 + /* If there is no data to send, just send out a pure ACK if
7562 + there is newdata. */
7563 + if(uip_flags & UIP_NEWDATA) {
7564 + uip_len = UIP_TCPIP_HLEN;
7565 + BUF->flags = TCP_ACK;
7566 + goto tcp_send_noopts;
7567 + }
7568 + }
7569 + goto drop;
7570 + case LAST_ACK:
7571 + /* We can close this connection if the peer has acknowledged our
7572 + FIN. This is indicated by the UIP_ACKDATA flag. */
7573 + if(uip_flags & UIP_ACKDATA) {
7574 + uip_connr->tcpstateflags = CLOSED;
7575 + uip_flags = UIP_CLOSE;
7576 + UIP_APPCALL();
7577 + }
7578 + break;
7579 +
7580 + case FIN_WAIT_1:
7581 + /* The application has closed the connection, but the remote host
7582 + hasn't closed its end yet. Thus we do nothing but wait for a
7583 + FIN from the other side. */
7584 + if(uip_len > 0) {
7585 + uip_add_rcv_nxt(uip_len);
7586 + }
7587 + if(BUF->flags & TCP_FIN) {
7588 + if(uip_flags & UIP_ACKDATA) {
7589 + uip_connr->tcpstateflags = TIME_WAIT;
7590 + uip_connr->timer = 0;
7591 + uip_connr->len = 0;
7592 + } else {
7593 + uip_connr->tcpstateflags = CLOSING;
7594 + }
7595 + uip_add_rcv_nxt(1);
7596 + uip_flags = UIP_CLOSE;
7597 + UIP_APPCALL();
7598 + goto tcp_send_ack;
7599 + } else if(uip_flags & UIP_ACKDATA) {
7600 + uip_connr->tcpstateflags = FIN_WAIT_2;
7601 + uip_connr->len = 0;
7602 + goto drop;
7603 + }
7604 + if(uip_len > 0) {
7605 + goto tcp_send_ack;
7606 + }
7607 + goto drop;
7608 +
7609 + case FIN_WAIT_2:
7610 + if(uip_len > 0) {
7611 + uip_add_rcv_nxt(uip_len);
7612 + }
7613 + if(BUF->flags & TCP_FIN) {
7614 + uip_connr->tcpstateflags = TIME_WAIT;
7615 + uip_connr->timer = 0;
7616 + uip_add_rcv_nxt(1);
7617 + uip_flags = UIP_CLOSE;
7618 + UIP_APPCALL();
7619 + goto tcp_send_ack;
7620 + }
7621 + if(uip_len > 0) {
7622 + goto tcp_send_ack;
7623 + }
7624 + goto drop;
7625 +
7626 + case TIME_WAIT:
7627 + goto tcp_send_ack;
7628 +
7629 + case CLOSING:
7630 + if(uip_flags & UIP_ACKDATA) {
7631 + uip_connr->tcpstateflags = TIME_WAIT;
7632 + uip_connr->timer = 0;
7633 + }
7634 + }
7635 + goto drop;
7636 +
7637 +
7638 + /* We jump here when we are ready to send the packet, and just want
7639 + to set the appropriate TCP sequence numbers in the TCP header. */
7640 + tcp_send_ack:
7641 + BUF->flags = TCP_ACK;
7642 + tcp_send_nodata:
7643 + uip_len = 40;
7644 + tcp_send_noopts:
7645 + BUF->tcpoffset = 5 << 4;
7646 + tcp_send:
7647 + /* We're done with the input processing. We are now ready to send a
7648 + reply. Our job is to fill in all the fields of the TCP and IP
7649 + headers before calculating the checksum and finally send the
7650 + packet. */
7651 + BUF->ackno[0] = uip_connr->rcv_nxt[0];
7652 + BUF->ackno[1] = uip_connr->rcv_nxt[1];
7653 + BUF->ackno[2] = uip_connr->rcv_nxt[2];
7654 + BUF->ackno[3] = uip_connr->rcv_nxt[3];
7655 +
7656 + BUF->seqno[0] = uip_connr->snd_nxt[0];
7657 + BUF->seqno[1] = uip_connr->snd_nxt[1];
7658 + BUF->seqno[2] = uip_connr->snd_nxt[2];
7659 + BUF->seqno[3] = uip_connr->snd_nxt[3];
7660 +
7661 + BUF->proto = UIP_PROTO_TCP;
7662 +
7663 + BUF->srcport = uip_connr->lport;
7664 + BUF->destport = uip_connr->rport;
7665 +
7666 + BUF->srcipaddr[0] = uip_hostaddr[0];
7667 + BUF->srcipaddr[1] = uip_hostaddr[1];
7668 + BUF->destipaddr[0] = uip_connr->ripaddr[0];
7669 + BUF->destipaddr[1] = uip_connr->ripaddr[1];
7670 +
7671 +
7672 + if(uip_connr->tcpstateflags & UIP_STOPPED) {
7673 + /* If the connection has issued uip_stop(), we advertise a zero
7674 + window so that the remote host will stop sending data. */
7675 + BUF->wnd[0] = BUF->wnd[1] = 0;
7676 + } else {
7677 + BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
7678 + BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
7679 + }
7680 +
7681 + tcp_send_noconn:
7682 +
7683 + BUF->len[0] = (uip_len >> 8);
7684 + BUF->len[1] = (uip_len & 0xff);
7685 +
7686 + /* Calculate TCP checksum. */
7687 + BUF->tcpchksum = 0;
7688 + BUF->tcpchksum = ~(uip_tcpchksum());
7689 +
7690 + //ip_send_nolen:
7691 +
7692 + BUF->vhl = 0x45;
7693 + BUF->tos = 0;
7694 + BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
7695 + BUF->ttl = UIP_TTL;
7696 + ++ipid;
7697 + BUF->ipid[0] = ipid >> 8;
7698 + BUF->ipid[1] = ipid & 0xff;
7699 +
7700 + /* Calculate IP checksum. */
7701 + BUF->ipchksum = 0;
7702 + BUF->ipchksum = ~(uip_ipchksum());
7703 +
7704 + UIP_STAT(++uip_stat.tcp.sent);
7705 + send:
7706 + UIP_STAT(++uip_stat.ip.sent);
7707 + /* Return and let the caller do the actual transmission. */
7708 + return;
7709 + drop:
7710 + uip_len = 0;
7711 + return;
7712 +}
7713 +/*-----------------------------------------------------------------------------------*/
7714 +/*unsigned short int
7715 +htons(unsigned short int val)
7716 +{
7717 + return HTONS(val);
7718 +}*/
7719 +/*-----------------------------------------------------------------------------------*/
7720 +/** @} */
7721 --- /dev/null
7722 +++ b/net/uip-0.9/uip.h
7723 @@ -0,0 +1,1066 @@
7724 +/**
7725 + * \addtogroup uip
7726 + * @{
7727 + */
7728 +
7729 +/**
7730 + * \file
7731 + * Header file for the uIP TCP/IP stack.
7732 + * \author Adam Dunkels <adam@dunkels.com>
7733 + *
7734 + * The uIP TCP/IP stack header file contains definitions for a number
7735 + * of C macros that are used by uIP programs as well as internal uIP
7736 + * structures, TCP/IP header structures and function declarations.
7737 + *
7738 + */
7739 +
7740 +
7741 +/*
7742 + * Copyright (c) 2001-2003, Adam Dunkels.
7743 + * All rights reserved.
7744 + *
7745 + * Redistribution and use in source and binary forms, with or without
7746 + * modification, are permitted provided that the following conditions
7747 + * are met:
7748 + * 1. Redistributions of source code must retain the above copyright
7749 + * notice, this list of conditions and the following disclaimer.
7750 + * 2. Redistributions in binary form must reproduce the above copyright
7751 + * notice, this list of conditions and the following disclaimer in the
7752 + * documentation and/or other materials provided with the distribution.
7753 + * 3. The name of the author may not be used to endorse or promote
7754 + * products derived from this software without specific prior
7755 + * written permission.
7756 + *
7757 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
7758 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7759 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7760 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
7761 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7762 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
7763 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
7764 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
7765 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
7766 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7767 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7768 + *
7769 + * This file is part of the uIP TCP/IP stack.
7770 + *
7771 + * $Id: uip.h,v 1.36.2.7 2003/10/07 13:47:51 adam Exp $
7772 + *
7773 + */
7774 +
7775 +#ifndef __UIP_H__
7776 +#define __UIP_H__
7777 +#include <linux/types.h>
7778 +#include <linux/string.h>
7779 +#include <linux/ctype.h>
7780 +#include <malloc.h>
7781 +#include <common.h>
7782 +
7783 +
7784 +#include "uipopt.h"
7785 +
7786 +/*-----------------------------------------------------------------------------------*/
7787 +/* First, the functions that should be called from the
7788 + * system. Initialization, the periodic timer and incoming packets are
7789 + * handled by the following three functions.
7790 + */
7791 +
7792 +/**
7793 + * \defgroup uipconffunc uIP configuration functions
7794 + * @{
7795 + *
7796 + * The uIP configuration functions are used for setting run-time
7797 + * parameters in uIP such as IP addresses.
7798 + */
7799 +
7800 +/**
7801 + * Set the IP address of this host.
7802 + *
7803 + * The IP address is represented as a 4-byte array where the first
7804 + * octet of the IP address is put in the first member of the 4-byte
7805 + * array.
7806 + *
7807 + * \param addr A pointer to a 4-byte representation of the IP address.
7808 + *
7809 + * \hideinitializer
7810 + */
7811 +#define uip_sethostaddr(addr) do { uip_hostaddr[0] = addr[0]; \
7812 + uip_hostaddr[1] = addr[1]; } while(0)
7813 +
7814 +/**
7815 + * Get the IP address of this host.
7816 + *
7817 + * The IP address is represented as a 4-byte array where the first
7818 + * octet of the IP address is put in the first member of the 4-byte
7819 + * array.
7820 + *
7821 + * \param addr A pointer to a 4-byte array that will be filled in with
7822 + * the currently configured IP address.
7823 + *
7824 + * \hideinitializer
7825 + */
7826 +#define uip_gethostaddr(addr) do { addr[0] = uip_hostaddr[0]; \
7827 + addr[1] = uip_hostaddr[1]; } while(0)
7828 +
7829 +/** @} */
7830 +
7831 +/**
7832 + * \defgroup uipinit uIP initialization functions
7833 + * @{
7834 + *
7835 + * The uIP initialization functions are used for booting uIP.
7836 + */
7837 +
7838 +/**
7839 + * uIP initialization function.
7840 + *
7841 + * This function should be called at boot up to initilize the uIP
7842 + * TCP/IP stack.
7843 + */
7844 +void uip_init(void);
7845 +
7846 +/** @} */
7847 +
7848 +/**
7849 + * \defgroup uipdevfunc uIP device driver functions
7850 + * @{
7851 + *
7852 + * These functions are used by a network device driver for interacting
7853 + * with uIP.
7854 + */
7855 +
7856 +/**
7857 + * Process an incoming packet.
7858 + *
7859 + * This function should be called when the device driver has received
7860 + * a packet from the network. The packet from the device driver must
7861 + * be present in the uip_buf buffer, and the length of the packet
7862 + * should be placed in the uip_len variable.
7863 + *
7864 + * When the function returns, there may be an outbound packet placed
7865 + * in the uip_buf packet buffer. If so, the uip_len variable is set to
7866 + * the length of the packet. If no packet is to be sent out, the
7867 + * uip_len variable is set to 0.
7868 + *
7869 + * The usual way of calling the function is presented by the source
7870 + * code below.
7871 + \code
7872 + uip_len = devicedriver_poll();
7873 + if(uip_len > 0) {
7874 + uip_input();
7875 + if(uip_len > 0) {
7876 + devicedriver_send();
7877 + }
7878 + }
7879 + \endcode
7880 + *
7881 + * \note If you are writing a uIP device driver that needs ARP
7882 + * (Address Resolution Protocol), e.g., when running uIP over
7883 + * Ethernet, you will need to call the uIP ARP code before calling
7884 + * this function:
7885 + \code
7886 + #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
7887 + uip_len = ethernet_devicedrver_poll();
7888 + if(uip_len > 0) {
7889 + if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
7890 + uip_arp_ipin();
7891 + uip_input();
7892 + if(uip_len > 0) {
7893 + uip_arp_out();
7894 + ethernet_devicedriver_send();
7895 + }
7896 + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
7897 + uip_arp_arpin();
7898 + if(uip_len > 0) {
7899 + ethernet_devicedriver_send();
7900 + }
7901 + }
7902 + \endcode
7903 + *
7904 + * \hideinitializer
7905 + */
7906 +#define uip_input() uip_process(UIP_DATA)
7907 +
7908 +/**
7909 + * Periodic processing for a connection identified by its number.
7910 + *
7911 + * This function does the necessary periodic processing (timers,
7912 + * polling) for a uIP TCP conneciton, and should be called when the
7913 + * periodic uIP timer goes off. It should be called for every
7914 + * connection, regardless of whether they are open of closed.
7915 + *
7916 + * When the function returns, it may have an outbound packet waiting
7917 + * for service in the uIP packet buffer, and if so the uip_len
7918 + * variable is set to a value larger than zero. The device driver
7919 + * should be called to send out the packet.
7920 + *
7921 + * The ususal way of calling the function is through a for() loop like
7922 + * this:
7923 + \code
7924 + for(i = 0; i < UIP_CONNS; ++i) {
7925 + uip_periodic(i);
7926 + if(uip_len > 0) {
7927 + devicedriver_send();
7928 + }
7929 + }
7930 + \endcode
7931 + *
7932 + * \note If you are writing a uIP device driver that needs ARP
7933 + * (Address Resolution Protocol), e.g., when running uIP over
7934 + * Ethernet, you will need to call the uip_arp_out() function before
7935 + * calling the device driver:
7936 + \code
7937 + for(i = 0; i < UIP_CONNS; ++i) {
7938 + uip_periodic(i);
7939 + if(uip_len > 0) {
7940 + uip_arp_out();
7941 + ethernet_devicedriver_send();
7942 + }
7943 + }
7944 + \endcode
7945 + *
7946 + * \param conn The number of the connection which is to be periodically polled.
7947 + *
7948 + * \hideinitializer
7949 + */
7950 +#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
7951 + uip_process(UIP_TIMER); } while (0)
7952 +
7953 +/**
7954 + * Periodic processing for a connection identified by a pointer to its structure.
7955 + *
7956 + * Same as uip_periodic() but takes a pointer to the actual uip_conn
7957 + * struct instead of an integer as its argument. This function can be
7958 + * used to force periodic processing of a specific connection.
7959 + *
7960 + * \param conn A pointer to the uip_conn struct for the connection to
7961 + * be processed.
7962 + *
7963 + * \hideinitializer
7964 + */
7965 +#define uip_periodic_conn(conn) do { uip_conn = conn; \
7966 + uip_process(UIP_TIMER); } while (0)
7967 +
7968 +#if UIP_UDP
7969 +/**
7970 + * Periodic processing for a UDP connection identified by its number.
7971 + *
7972 + * This function is essentially the same as uip_prerioic(), but for
7973 + * UDP connections. It is called in a similar fashion as the
7974 + * uip_periodic() function:
7975 + \code
7976 + for(i = 0; i < UIP_UDP_CONNS; i++) {
7977 + uip_udp_periodic(i);
7978 + if(uip_len > 0) {
7979 + devicedriver_send();
7980 + }
7981 + }
7982 + \endcode
7983 + *
7984 + * \note As for the uip_periodic() function, special care has to be
7985 + * taken when using uIP together with ARP and Ethernet:
7986 + \code
7987 + for(i = 0; i < UIP_UDP_CONNS; i++) {
7988 + uip_udp_periodic(i);
7989 + if(uip_len > 0) {
7990 + uip_arp_out();
7991 + ethernet_devicedriver_send();
7992 + }
7993 + }
7994 + \endcode
7995 + *
7996 + * \param conn The number of the UDP connection to be processed.
7997 + *
7998 + * \hideinitializer
7999 + */
8000 +#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
8001 + uip_process(UIP_UDP_TIMER); } while (0)
8002 +
8003 +/**
8004 + * Periodic processing for a UDP connection identified by a pointer to
8005 + * its structure.
8006 + *
8007 + * Same as uip_udp_periodic() but takes a pointer to the actual
8008 + * uip_conn struct instead of an integer as its argument. This
8009 + * function can be used to force periodic processing of a specific
8010 + * connection.
8011 + *
8012 + * \param conn A pointer to the uip_udp_conn struct for the connection
8013 + * to be processed.
8014 + *
8015 + * \hideinitializer
8016 + */
8017 +#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
8018 + uip_process(UIP_UDP_TIMER); } while (0)
8019 +
8020 +
8021 +#endif /* UIP_UDP */
8022 +
8023 +/**
8024 + * The uIP packet buffer.
8025 + *
8026 + * The uip_buf array is used to hold incoming and outgoing
8027 + * packets. The device driver should place incoming data into this
8028 + * buffer. When sending data, the device driver should read the link
8029 + * level headers and the TCP/IP headers from this buffer. The size of
8030 + * the link level headers is configured by the UIP_LLH_LEN define.
8031 + *
8032 + * \note The application data need not be placed in this buffer, so
8033 + * the device driver must read it from the place pointed to by the
8034 + * uip_appdata pointer as illustrated by the following example:
8035 + \code
8036 + void
8037 + devicedriver_send(void)
8038 + {
8039 + hwsend(&uip_buf[0], UIP_LLH_LEN);
8040 + hwsend(&uip_buf[UIP_LLH_LEN], 40);
8041 + hwsend(uip_appdata, uip_len - 40 - UIP_LLH_LEN);
8042 + }
8043 + \endcode
8044 + */
8045 +extern u8_t uip_buf[UIP_BUFSIZE+2];
8046 +
8047 +/** @} */
8048 +
8049 +/*-----------------------------------------------------------------------------------*/
8050 +/* Functions that are used by the uIP application program. Opening and
8051 + * closing connections, sending and receiving data, etc. is all
8052 + * handled by the functions below.
8053 +*/
8054 +/**
8055 + * \defgroup uipappfunc uIP application functions
8056 + * @{
8057 + *
8058 + * Functions used by an application running of top of uIP.
8059 + */
8060 +
8061 +/**
8062 + * Start listening to the specified port.
8063 + *
8064 + * \note Since this function expects the port number in network byte
8065 + * order, a conversion using HTONS() or htons() is necessary.
8066 + *
8067 + \code
8068 + uip_listen(HTONS(80));
8069 + \endcode
8070 + *
8071 + * \param port A 16-bit port number in network byte order.
8072 + */
8073 +void uip_listen(u16_t port);
8074 +
8075 +/**
8076 + * Stop listening to the specified port.
8077 + *
8078 + * \note Since this function expects the port number in network byte
8079 + * order, a conversion using HTONS() or htons() is necessary.
8080 + *
8081 + \code
8082 + uip_unlisten(HTONS(80));
8083 + \endcode
8084 + *
8085 + * \param port A 16-bit port number in network byte order.
8086 + */
8087 +void uip_unlisten(u16_t port);
8088 +
8089 +/**
8090 + * Connect to a remote host using TCP.
8091 + *
8092 + * This function is used to start a new connection to the specified
8093 + * port on the specied host. It allocates a new connection identifier,
8094 + * sets the connection to the SYN_SENT state and sets the
8095 + * retransmission timer to 0. This will cause a TCP SYN segment to be
8096 + * sent out the next time this connection is periodically processed,
8097 + * which usually is done within 0.5 seconds after the call to
8098 + * uip_connect().
8099 + *
8100 + * \note This function is avaliable only if support for active open
8101 + * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h.
8102 + *
8103 + * \note Since this function requires the port number to be in network
8104 + * byte order, a convertion using HTONS() or htons() is necessary.
8105 + *
8106 + \code
8107 + u16_t ipaddr[2];
8108 +
8109 + uip_ipaddr(ipaddr, 192,168,1,2);
8110 + uip_connect(ipaddr, HTONS(80));
8111 + \endcode
8112 + *
8113 + * \param ripaddr A pointer to a 4-byte array representing the IP
8114 + * address of the remote hot.
8115 + *
8116 + * \param port A 16-bit port number in network byte order.
8117 + *
8118 + * \return A pointer to the uIP connection identifier for the new connection,
8119 + * or NULL if no connection could be allocated.
8120 + *
8121 + */
8122 +struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port);
8123 +
8124 +
8125 +
8126 +/**
8127 + * \internal
8128 + *
8129 + * Check if a connection has outstanding (i.e., unacknowledged) data.
8130 + *
8131 + * \param conn A pointer to the uip_conn structure for the connection.
8132 + *
8133 + * \hideinitializer
8134 + */
8135 +#define uip_outstanding(conn) ((conn)->len)
8136 +
8137 +/**
8138 + * Send data on the current connection.
8139 + *
8140 + * This function is used to send out a single segment of TCP
8141 + * data. Only applications that have been invoked by uIP for event
8142 + * processing can send data.
8143 + *
8144 + * The amount of data that actually is sent out after a call to this
8145 + * funcion is determined by the maximum amount of data TCP allows. uIP
8146 + * will automatically crop the data so that only the appropriate
8147 + * amount of data is sent. The function uip_mss() can be used to query
8148 + * uIP for the amount of data that actually will be sent.
8149 + *
8150 + * \note This function does not guarantee that the sent data will
8151 + * arrive at the destination. If the data is lost in the network, the
8152 + * application will be invoked with the uip_rexmit() event being
8153 + * set. The application will then have to resend the data using this
8154 + * function.
8155 + *
8156 + * \param data A pointer to the data which is to be sent.
8157 + *
8158 + * \param len The maximum amount of data bytes to be sent.
8159 + *
8160 + * \hideinitializer
8161 + */
8162 +#define uip_send(data, len) do { uip_sappdata = (data); uip_slen = (len);} while(0)
8163 +
8164 +/**
8165 + * The length of any incoming data that is currently avaliable (if avaliable)
8166 + * in the uip_appdata buffer.
8167 + *
8168 + * The test function uip_data() must first be used to check if there
8169 + * is any data available at all.
8170 + *
8171 + * \hideinitializer
8172 + */
8173 +#define uip_datalen() uip_len
8174 +
8175 +/**
8176 + * The length of any out-of-band data (urgent data) that has arrived
8177 + * on the connection.
8178 + *
8179 + * \note The configuration parameter UIP_URGDATA must be set for this
8180 + * function to be enabled.
8181 + *
8182 + * \hideinitializer
8183 + */
8184 +#define uip_urgdatalen() uip_urglen
8185 +
8186 +/**
8187 + * Close the current connection.
8188 + *
8189 + * This function will close the current connection in a nice way.
8190 + *
8191 + * \hideinitializer
8192 + */
8193 +#define uip_close() (uip_flags = UIP_CLOSE)
8194 +
8195 +/**
8196 + * Abort the current connection.
8197 + *
8198 + * This function will abort (reset) the current connection, and is
8199 + * usually used when an error has occured that prevents using the
8200 + * uip_close() function.
8201 + *
8202 + * \hideinitializer
8203 + */
8204 +#define uip_abort() (uip_flags = UIP_ABORT)
8205 +
8206 +/**
8207 + * Tell the sending host to stop sending data.
8208 + *
8209 + * This function will close our receiver's window so that we stop
8210 + * receiving data for the current connection.
8211 + *
8212 + * \hideinitializer
8213 + */
8214 +#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED)
8215 +
8216 +/**
8217 + * Find out if the current connection has been previously stopped with
8218 + * uip_stop().
8219 + *
8220 + * \hideinitializer
8221 + */
8222 +#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED)
8223 +
8224 +/**
8225 + * Restart the current connection, if is has previously been stopped
8226 + * with uip_stop().
8227 + *
8228 + * This function will open the receiver's window again so that we
8229 + * start receiving data for the current connection.
8230 + *
8231 + * \hideinitializer
8232 + */
8233 +#define uip_restart() do { uip_flags |= UIP_NEWDATA; \
8234 + uip_conn->tcpstateflags &= ~UIP_STOPPED; \
8235 + } while(0)
8236 +
8237 +
8238 +/* uIP tests that can be made to determine in what state the current
8239 + connection is, and what the application function should do. */
8240 +
8241 +/**
8242 + * Is new incoming data available?
8243 + *
8244 + * Will reduce to non-zero if there is new data for the application
8245 + * present at the uip_appdata pointer. The size of the data is
8246 + * avaliable through the uip_len variable.
8247 + *
8248 + * \hideinitializer
8249 + */
8250 +#define uip_newdata() (uip_flags & UIP_NEWDATA)
8251 +
8252 +/**
8253 + * Has previously sent data been acknowledged?
8254 + *
8255 + * Will reduce to non-zero if the previously sent data has been
8256 + * acknowledged by the remote host. This means that the application
8257 + * can send new data.
8258 + *
8259 + * \hideinitializer
8260 + */
8261 +#define uip_acked() (uip_flags & UIP_ACKDATA)
8262 +
8263 +/**
8264 + * Has the connection just been connected?
8265 + *
8266 + * Reduces to non-zero if the current connection has been connected to
8267 + * a remote host. This will happen both if the connection has been
8268 + * actively opened (with uip_connect()) or passively opened (with
8269 + * uip_listen()).
8270 + *
8271 + * \hideinitializer
8272 + */
8273 +#define uip_connected() (uip_flags & UIP_CONNECTED)
8274 +
8275 +/**
8276 + * Has the connection been closed by the other end?
8277 + *
8278 + * Is non-zero if the connection has been closed by the remote
8279 + * host. The application may then do the necessary clean-ups.
8280 + *
8281 + * \hideinitializer
8282 + */
8283 +#define uip_closed() (uip_flags & UIP_CLOSE)
8284 +
8285 +/**
8286 + * Has the connection been aborted by the other end?
8287 + *
8288 + * Non-zero if the current connection has been aborted (reset) by the
8289 + * remote host.
8290 + *
8291 + * \hideinitializer
8292 + */
8293 +#define uip_aborted() (uip_flags & UIP_ABORT)
8294 +
8295 +/**
8296 + * Has the connection timed out?
8297 + *
8298 + * Non-zero if the current connection has been aborted due to too many
8299 + * retransmissions.
8300 + *
8301 + * \hideinitializer
8302 + */
8303 +#define uip_timedout() (uip_flags & UIP_TIMEDOUT)
8304 +
8305 +/**
8306 + * Do we need to retransmit previously data?
8307 + *
8308 + * Reduces to non-zero if the previously sent data has been lost in
8309 + * the network, and the application should retransmit it. The
8310 + * application should send the exact same data as it did the last
8311 + * time, using the uip_send() function.
8312 + *
8313 + * \hideinitializer
8314 + */
8315 +#define uip_rexmit() (uip_flags & UIP_REXMIT)
8316 +
8317 +/**
8318 + * Is the connection being polled by uIP?
8319 + *
8320 + * Is non-zero if the reason the application is invoked is that the
8321 + * current connection has been idle for a while and should be
8322 + * polled.
8323 + *
8324 + * The polling event can be used for sending data without having to
8325 + * wait for the remote host to send data.
8326 + *
8327 + * \hideinitializer
8328 + */
8329 +#define uip_poll() (uip_flags & UIP_POLL)
8330 +
8331 +/**
8332 + * Get the initial maxium segment size (MSS) of the current
8333 + * connection.
8334 + *
8335 + * \hideinitializer
8336 + */
8337 +#define uip_initialmss() (uip_conn->initialmss)
8338 +
8339 +/**
8340 + * Get the current maxium segment size that can be sent on the current
8341 + * connection.
8342 + *
8343 + * The current maxiumum segment size that can be sent on the
8344 + * connection is computed from the receiver's window and the MSS of
8345 + * the connection (which also is available by calling
8346 + * uip_initialmss()).
8347 + *
8348 + * \hideinitializer
8349 + */
8350 +#define uip_mss() (uip_conn->mss)
8351 +
8352 +/**
8353 + * Set up a new UDP connection.
8354 + *
8355 + * \param ripaddr A pointer to a 4-byte structure representing the IP
8356 + * address of the remote host.
8357 + *
8358 + * \param rport The remote port number in network byte order.
8359 + *
8360 + * \return The uip_udp_conn structure for the new connection or NULL
8361 + * if no connection could be allocated.
8362 + */
8363 +struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport);
8364 +
8365 +/**
8366 + * Removed a UDP connection.
8367 + *
8368 + * \param conn A pointer to the uip_udp_conn structure for the connection.
8369 + *
8370 + * \hideinitializer
8371 + */
8372 +#define uip_udp_remove(conn) (conn)->lport = 0
8373 +
8374 +/**
8375 + * Send a UDP datagram of length len on the current connection.
8376 + *
8377 + * This function can only be called in response to a UDP event (poll
8378 + * or newdata). The data must be present in the uip_buf buffer, at the
8379 + * place pointed to by the uip_appdata pointer.
8380 + *
8381 + * \param len The length of the data in the uip_buf buffer.
8382 + *
8383 + * \hideinitializer
8384 + */
8385 +#define uip_udp_send(len) uip_slen = (len)
8386 +
8387 +/** @} */
8388 +
8389 +/* uIP convenience and converting functions. */
8390 +
8391 +/**
8392 + * \defgroup uipconvfunc uIP conversion functions
8393 + * @{
8394 + *
8395 + * These functions can be used for converting between different data
8396 + * formats used by uIP.
8397 + */
8398 +
8399 +/**
8400 + * Pack an IP address into a 4-byte array which is used by uIP to
8401 + * represent IP addresses.
8402 + *
8403 + * Example:
8404 + \code
8405 + u16_t ipaddr[2];
8406 +
8407 + uip_ipaddr(&ipaddr, 192,168,1,2);
8408 + \endcode
8409 + *
8410 + * \param addr A pointer to a 4-byte array that will be filled in with
8411 + * the IP addres.
8412 + * \param addr0 The first octet of the IP address.
8413 + * \param addr1 The second octet of the IP address.
8414 + * \param addr2 The third octet of the IP address.
8415 + * \param addr3 The forth octet of the IP address.
8416 + *
8417 + * \hideinitializer
8418 + */
8419 +#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
8420 + (addr)[0] = HTONS(((addr0) << 8) | (addr1)); \
8421 + (addr)[1] = HTONS(((addr2) << 8) | (addr3)); \
8422 + } while(0)
8423 +
8424 +/**
8425 + * Convert 16-bit quantity from host byte order to network byte order.
8426 + *
8427 + * This macro is primarily used for converting constants from host
8428 + * byte order to network byte order. For converting variables to
8429 + * network byte order, use the htons() function instead.
8430 + *
8431 + * \hideinitializer
8432 + */
8433 +#ifndef HTONS
8434 +# if BYTE_ORDER == BIG_ENDIAN
8435 +# define HTONS(n) (n)
8436 +# else /* BYTE_ORDER == BIG_ENDIAN */
8437 +# define HTONS(n) ((((u16_t)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8))
8438 +# endif /* BYTE_ORDER == BIG_ENDIAN */
8439 +#endif /* HTONS */
8440 +
8441 +/**
8442 + * Convert 16-bit quantity from host byte order to network byte order.
8443 + *
8444 + * This function is primarily used for converting variables from host
8445 + * byte order to network byte order. For converting constants to
8446 + * network byte order, use the HTONS() macro instead.
8447 + */
8448 +#ifndef htons
8449 +u16_t htons(u16_t val);
8450 +#endif /* htons */
8451 +
8452 +/** @} */
8453 +
8454 +/**
8455 + * Pointer to the application data in the packet buffer.
8456 + *
8457 + * This pointer points to the application data when the application is
8458 + * called. If the application wishes to send data, the application may
8459 + * use this space to write the data into before calling uip_send().
8460 + */
8461 +extern volatile u8_t *uip_appdata;
8462 +extern volatile u8_t *uip_sappdata;
8463 +
8464 +#if UIP_URGDATA > 0
8465 +/* u8_t *uip_urgdata:
8466 + *
8467 + * This pointer points to any urgent data that has been received. Only
8468 + * present if compiled with support for urgent data (UIP_URGDATA).
8469 + */
8470 +extern volatile u8_t *uip_urgdata;
8471 +#endif /* UIP_URGDATA > 0 */
8472 +
8473 +
8474 +/* u[8|16]_t uip_len:
8475 + *
8476 + * When the application is called, uip_len contains the length of any
8477 + * new data that has been received from the remote host. The
8478 + * application should set this variable to the size of any data that
8479 + * the application wishes to send. When the network device driver
8480 + * output function is called, uip_len should contain the length of the
8481 + * outgoing packet.
8482 + */
8483 +extern volatile u16_t uip_len, uip_slen;
8484 +
8485 +#if UIP_URGDATA > 0
8486 +extern volatile u8_t uip_urglen, uip_surglen;
8487 +#endif /* UIP_URGDATA > 0 */
8488 +
8489 +
8490 +/**
8491 + * Representation of a uIP TCP connection.
8492 + *
8493 + * The uip_conn structure is used for identifying a connection. All
8494 + * but one field in the structure are to be considered read-only by an
8495 + * application. The only exception is the appstate field whos purpose
8496 + * is to let the application store application-specific state (e.g.,
8497 + * file pointers) for the connection. The size of this field is
8498 + * configured in the "uipopt.h" header file.
8499 + */
8500 +struct uip_conn {
8501 + u16_t ripaddr[2]; /**< The IP address of the remote host. */
8502 +
8503 + u16_t lport; /**< The local TCP port, in network byte order. */
8504 + u16_t rport; /**< The local remote TCP port, in network byte
8505 + order. */
8506 +
8507 + u8_t rcv_nxt[4]; /**< The sequence number that we expect to
8508 + receive next. */
8509 + u8_t snd_nxt[4]; /**< The sequence number that was last sent by
8510 + us. */
8511 + u16_t len; /**< Length of the data that was previously sent. */
8512 + u16_t mss; /**< Current maximum segment size for the
8513 + connection. */
8514 + u16_t initialmss; /**< Initial maximum segment size for the
8515 + connection. */
8516 + u8_t sa; /**< Retransmission time-out calculation state
8517 + variable. */
8518 + u8_t sv; /**< Retransmission time-out calculation state
8519 + variable. */
8520 + u8_t rto; /**< Retransmission time-out. */
8521 + u8_t tcpstateflags; /**< TCP state and flags. */
8522 + u8_t timer; /**< The retransmission timer. */
8523 + u8_t nrtx; /**< The number of retransmissions for the last
8524 + segment sent. */
8525 +
8526 + /** The application state. */
8527 + u8_t appstate[UIP_APPSTATE_SIZE];
8528 +};
8529 +
8530 +
8531 +/* Pointer to the current connection. */
8532 +extern struct uip_conn *uip_conn;
8533 +/* The array containing all uIP connections. */
8534 +extern struct uip_conn uip_conns[UIP_CONNS];
8535 +/**
8536 + * \addtogroup uiparch
8537 + * @{
8538 + */
8539 +
8540 +/**
8541 + * 4-byte array used for the 32-bit sequence number calculations.
8542 + */
8543 +extern volatile u8_t uip_acc32[4];
8544 +
8545 +/** @} */
8546 +
8547 +
8548 +#if UIP_UDP
8549 +/**
8550 + * Representation of a uIP UDP connection.
8551 + */
8552 +struct uip_udp_conn {
8553 + u16_t ripaddr[2]; /**< The IP address of the remote peer. */
8554 + u16_t lport; /**< The local port number in network byte order. */
8555 + u16_t rport; /**< The remote port number in network byte order. */
8556 +};
8557 +
8558 +extern struct uip_udp_conn *uip_udp_conn;
8559 +extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
8560 +#endif /* UIP_UDP */
8561 +
8562 +/**
8563 + * The structure holding the TCP/IP statistics that are gathered if
8564 + * UIP_STATISTICS is set to 1.
8565 + *
8566 + */
8567 +struct uip_stats {
8568 + struct {
8569 + uip_stats_t drop; /**< Number of dropped packets at the IP
8570 + layer. */
8571 + uip_stats_t recv; /**< Number of received packets at the IP
8572 + layer. */
8573 + uip_stats_t sent; /**< Number of sent packets at the IP
8574 + layer. */
8575 + uip_stats_t vhlerr; /**< Number of packets dropped due to wrong
8576 + IP version or header length. */
8577 + uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
8578 + IP length, high byte. */
8579 + uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
8580 + IP length, low byte. */
8581 + uip_stats_t fragerr; /**< Number of packets dropped since they
8582 + were IP fragments. */
8583 + uip_stats_t chkerr; /**< Number of packets dropped due to IP
8584 + checksum errors. */
8585 + uip_stats_t protoerr; /**< Number of packets dropped since they
8586 + were neither ICMP, UDP nor TCP. */
8587 + } ip; /**< IP statistics. */
8588 + struct {
8589 + uip_stats_t drop; /**< Number of dropped ICMP packets. */
8590 + uip_stats_t recv; /**< Number of received ICMP packets. */
8591 + uip_stats_t sent; /**< Number of sent ICMP packets. */
8592 + uip_stats_t typeerr; /**< Number of ICMP packets with a wrong
8593 + type. */
8594 + } icmp; /**< ICMP statistics. */
8595 + struct {
8596 + uip_stats_t drop; /**< Number of dropped TCP segments. */
8597 + uip_stats_t recv; /**< Number of recived TCP segments. */
8598 + uip_stats_t sent; /**< Number of sent TCP segments. */
8599 + uip_stats_t chkerr; /**< Number of TCP segments with a bad
8600 + checksum. */
8601 + uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK
8602 + number. */
8603 + uip_stats_t rst; /**< Number of recevied TCP RST (reset) segments. */
8604 + uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */
8605 + uip_stats_t syndrop; /**< Number of dropped SYNs due to too few
8606 + connections was avaliable. */
8607 + uip_stats_t synrst; /**< Number of SYNs for closed ports,
8608 + triggering a RST. */
8609 + } tcp; /**< TCP statistics. */
8610 +};
8611 +
8612 +/**
8613 + * The uIP TCP/IP statistics.
8614 + *
8615 + * This is the variable in which the uIP TCP/IP statistics are gathered.
8616 + */
8617 +extern struct uip_stats uip_stat;
8618 +
8619 +
8620 +/*-----------------------------------------------------------------------------------*/
8621 +/* All the stuff below this point is internal to uIP and should not be
8622 + * used directly by an application or by a device driver.
8623 + */
8624 +/*-----------------------------------------------------------------------------------*/
8625 +/* u8_t uip_flags:
8626 + *
8627 + * When the application is called, uip_flags will contain the flags
8628 + * that are defined in this file. Please read below for more
8629 + * infomation.
8630 + */
8631 +extern volatile u8_t uip_flags;
8632 +
8633 +/* The following flags may be set in the global variable uip_flags
8634 + before calling the application callback. The UIP_ACKDATA and
8635 + UIP_NEWDATA flags may both be set at the same time, whereas the
8636 + others are mutualy exclusive. Note that these flags should *NOT* be
8637 + accessed directly, but through the uIP functions/macros. */
8638 +
8639 +#define UIP_ACKDATA 1 /* Signifies that the outstanding data was
8640 + acked and the application should send
8641 + out new data instead of retransmitting
8642 + the last data. */
8643 +#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent
8644 + us new data. */
8645 +#define UIP_REXMIT 4 /* Tells the application to retransmit the
8646 + data that was last sent. */
8647 +#define UIP_POLL 8 /* Used for polling the application, to
8648 + check if the application has data that
8649 + it wants to send. */
8650 +#define UIP_CLOSE 16 /* The remote host has closed the
8651 + connection, thus the connection has
8652 + gone away. Or the application signals
8653 + that it wants to close the
8654 + connection. */
8655 +#define UIP_ABORT 32 /* The remote host has aborted the
8656 + connection, thus the connection has
8657 + gone away. Or the application signals
8658 + that it wants to abort the
8659 + connection. */
8660 +#define UIP_CONNECTED 64 /* We have got a connection from a remote
8661 + host and have set up a new connection
8662 + for it, or an active connection has
8663 + been successfully established. */
8664 +
8665 +#define UIP_TIMEDOUT 128 /* The connection has been aborted due to
8666 + too many retransmissions. */
8667 +
8668 +
8669 +/* uip_process(flag):
8670 + *
8671 + * The actual uIP function which does all the work.
8672 + */
8673 +void uip_process(u8_t flag);
8674 +
8675 +/* The following flags are passed as an argument to the uip_process()
8676 + function. They are used to distinguish between the two cases where
8677 + uip_process() is called. It can be called either because we have
8678 + incoming data that should be processed, or because the periodic
8679 + timer has fired. */
8680 +
8681 +#define UIP_DATA 1 /* Tells uIP that there is incoming data in
8682 + the uip_buf buffer. The length of the
8683 + data is stored in the global variable
8684 + uip_len. */
8685 +#define UIP_TIMER 2 /* Tells uIP that the periodic timer has
8686 + fired. */
8687 +#if UIP_UDP
8688 +#define UIP_UDP_TIMER 3
8689 +#endif /* UIP_UDP */
8690 +
8691 +/* The TCP states used in the uip_conn->tcpstateflags. */
8692 +#define CLOSED 0
8693 +#define SYN_RCVD 1
8694 +#define SYN_SENT 2
8695 +#define ESTABLISHED 3
8696 +#define FIN_WAIT_1 4
8697 +#define FIN_WAIT_2 5
8698 +#define CLOSING 6
8699 +#define TIME_WAIT 7
8700 +#define LAST_ACK 8
8701 +#define TS_MASK 15
8702 +
8703 +#define UIP_STOPPED 16
8704 +
8705 +#define UIP_TCPIP_HLEN 40
8706 +
8707 +/* The TCP and IP headers. */
8708 +typedef struct {
8709 + /* IP header. */
8710 + u8_t vhl,
8711 + tos,
8712 + len[2],
8713 + ipid[2],
8714 + ipoffset[2],
8715 + ttl,
8716 + proto;
8717 + u16_t ipchksum;
8718 + u16_t srcipaddr[2],
8719 + destipaddr[2];
8720 +
8721 + /* TCP header. */
8722 + u16_t srcport,
8723 + destport;
8724 + u8_t seqno[4],
8725 + ackno[4],
8726 + tcpoffset,
8727 + flags,
8728 + wnd[2];
8729 + u16_t tcpchksum;
8730 + u8_t urgp[2];
8731 + u8_t optdata[4];
8732 +} uip_tcpip_hdr;
8733 +
8734 +/* The ICMP and IP headers. */
8735 +typedef struct {
8736 + /* IP header. */
8737 + u8_t vhl,
8738 + tos,
8739 + len[2],
8740 + ipid[2],
8741 + ipoffset[2],
8742 + ttl,
8743 + proto;
8744 + u16_t ipchksum;
8745 + u16_t srcipaddr[2],
8746 + destipaddr[2];
8747 + /* ICMP (echo) header. */
8748 + u8_t type, icode;
8749 + u16_t icmpchksum;
8750 + u16_t id, seqno;
8751 +} uip_icmpip_hdr;
8752 +
8753 +
8754 +/* The UDP and IP headers. */
8755 +typedef struct {
8756 + /* IP header. */
8757 + u8_t vhl,
8758 + tos,
8759 + len[2],
8760 + ipid[2],
8761 + ipoffset[2],
8762 + ttl,
8763 + proto;
8764 + u16_t ipchksum;
8765 + u16_t srcipaddr[2],
8766 + destipaddr[2];
8767 +
8768 + /* UDP header. */
8769 + u16_t srcport,
8770 + destport;
8771 + u16_t udplen;
8772 + u16_t udpchksum;
8773 +} uip_udpip_hdr;
8774 +
8775 +#define UIP_PROTO_ICMP 1
8776 +#define UIP_PROTO_TCP 6
8777 +#define UIP_PROTO_UDP 17
8778 +
8779 +#if UIP_FIXEDADDR
8780 +extern const u16_t uip_hostaddr[2];
8781 +#else /* UIP_FIXEDADDR */
8782 +extern u16_t uip_hostaddr[2];
8783 +#endif /* UIP_FIXEDADDR */
8784 +
8785 +#endif /* __UIP_H__ */
8786 +
8787 +
8788 +/** @} */
8789 +
8790 --- /dev/null
8791 +++ b/net/uip-0.9/uipopt.h
8792 @@ -0,0 +1,557 @@
8793 +/**
8794 + * \defgroup uipopt Configuration options for uIP
8795 + * @{
8796 + *
8797 + * uIP is configured using the per-project configuration file
8798 + * "uipopt.h". This file contains all compile-time options for uIP and
8799 + * should be tweaked to match each specific project. The uIP
8800 + * distribution contains a documented example "uipopt.h" that can be
8801 + * copied and modified for each project.
8802 + */
8803 +
8804 +/**
8805 + * \file
8806 + * Configuration options for uIP.
8807 + * \author Adam Dunkels <adam@dunkels.com>
8808 + *
8809 + * This file is used for tweaking various configuration options for
8810 + * uIP. You should make a copy of this file into one of your project's
8811 + * directories instead of editing this example "uipopt.h" file that
8812 + * comes with the uIP distribution.
8813 + */
8814 +
8815 +/*
8816 + * Copyright (c) 2001-2003, Adam Dunkels.
8817 + * All rights reserved.
8818 + *
8819 + * Redistribution and use in source and binary forms, with or without
8820 + * modification, are permitted provided that the following conditions
8821 + * are met:
8822 + * 1. Redistributions of source code must retain the above copyright
8823 + * notice, this list of conditions and the following disclaimer.
8824 + * 2. Redistributions in binary form must reproduce the above copyright
8825 + * notice, this list of conditions and the following disclaimer in the
8826 + * documentation and/or other materials provided with the distribution.
8827 + * 3. The name of the author may not be used to endorse or promote
8828 + * products derived from this software without specific prior
8829 + * written permission.
8830 + *
8831 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
8832 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8833 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8834 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
8835 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8836 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
8837 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8838 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
8839 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
8840 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8841 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8842 + *
8843 + * This file is part of the uIP TCP/IP stack.
8844 + *
8845 + * $Id: uipopt.h,v 1.16.2.5 2003/10/07 13:22:51 adam Exp $
8846 + *
8847 + */
8848 +
8849 +#ifndef __UIPOPT_H__
8850 +#define __UIPOPT_H__
8851 +
8852 +/*------------------------------------------------------------------------------*/
8853 +/**
8854 + * \defgroup uipopttypedef uIP type definitions
8855 + * @{
8856 + */
8857 +
8858 +/**
8859 + * The 8-bit unsigned data type.
8860 + *
8861 + * This may have to be tweaked for your particular compiler. "unsigned
8862 + * char" works for most compilers.
8863 + */
8864 +typedef unsigned char u8_t;
8865 +
8866 +/**
8867 + * The 16-bit unsigned data type.
8868 + *
8869 + * This may have to be tweaked for your particular compiler. "unsigned
8870 + * short" works for most compilers.
8871 + */
8872 +typedef unsigned short u16_t;
8873 +
8874 +/**
8875 + * The statistics data type.
8876 + *
8877 + * This datatype determines how high the statistics counters are able
8878 + * to count.
8879 + */
8880 +typedef unsigned short uip_stats_t;
8881 +
8882 +/** @} */
8883 +
8884 +/*------------------------------------------------------------------------------*/
8885 +
8886 +/**
8887 + * \defgroup uipoptstaticconf Static configuration options
8888 + * @{
8889 + *
8890 + * These configuration options can be used for setting the IP address
8891 + * settings statically, but only if UIP_FIXEDADDR is set to 1. The
8892 + * configuration options for a specific node includes IP address,
8893 + * netmask and default router as well as the Ethernet address. The
8894 + * netmask, default router and Ethernet address are appliciable only
8895 + * if uIP should be run over Ethernet.
8896 + *
8897 + * All of these should be changed to suit your project.
8898 +*/
8899 +
8900 +/**
8901 + * Determines if uIP should use a fixed IP address or not.
8902 + *
8903 + * If uIP should use a fixed IP address, the settings are set in the
8904 + * uipopt.h file. If not, the macros uip_sethostaddr(),
8905 + * uip_setdraddr() and uip_setnetmask() should be used instead.
8906 + *
8907 + * \hideinitializer
8908 + */
8909 +#define UIP_FIXEDADDR 0
8910 +
8911 +/**
8912 + * Ping IP address asignment.
8913 + *
8914 + * uIP uses a "ping" packets for setting its own IP address if this
8915 + * option is set. If so, uIP will start with an empty IP address and
8916 + * the destination IP address of the first incoming "ping" (ICMP echo)
8917 + * packet will be used for setting the hosts IP address.
8918 + *
8919 + * \note This works only if UIP_FIXEDADDR is 0.
8920 + *
8921 + * \hideinitializer
8922 + */
8923 +#define UIP_PINGADDRCONF 0
8924 +
8925 +#define UIP_IPADDR0 192 /**< The first octet of the IP address of
8926 + this uIP node, if UIP_FIXEDADDR is
8927 + 1. \hideinitializer */
8928 +#define UIP_IPADDR1 168 /**< The second octet of the IP address of
8929 + this uIP node, if UIP_FIXEDADDR is
8930 + 1. \hideinitializer */
8931 +#define UIP_IPADDR2 0 /**< The third octet of the IP address of
8932 + this uIP node, if UIP_FIXEDADDR is
8933 + 1. \hideinitializer */
8934 +#define UIP_IPADDR3 250 /**< The fourth octet of the IP address of
8935 + this uIP node, if UIP_FIXEDADDR is
8936 + 1. \hideinitializer */
8937 +
8938 +#define UIP_NETMASK0 255 /**< The first octet of the netmask of
8939 + this uIP node, if UIP_FIXEDADDR is
8940 + 1. \hideinitializer */
8941 +#define UIP_NETMASK1 255 /**< The second octet of the netmask of
8942 + this uIP node, if UIP_FIXEDADDR is
8943 + 1. \hideinitializer */
8944 +#define UIP_NETMASK2 255 /**< The third octet of the netmask of
8945 + this uIP node, if UIP_FIXEDADDR is
8946 + 1. \hideinitializer */
8947 +#define UIP_NETMASK3 0 /**< The fourth octet of the netmask of
8948 + this uIP node, if UIP_FIXEDADDR is
8949 + 1. \hideinitializer */
8950 +
8951 +#define UIP_DRIPADDR0 192 /**< The first octet of the IP address of
8952 + the default router, if UIP_FIXEDADDR is
8953 + 1. \hideinitializer */
8954 +#define UIP_DRIPADDR1 168 /**< The second octet of the IP address of
8955 + the default router, if UIP_FIXEDADDR is
8956 + 1. \hideinitializer */
8957 +#define UIP_DRIPADDR2 0 /**< The third octet of the IP address of
8958 + the default router, if UIP_FIXEDADDR is
8959 + 1. \hideinitializer */
8960 +#define UIP_DRIPADDR3 1 /**< The fourth octet of the IP address of
8961 + the default router, if UIP_FIXEDADDR is
8962 + 1. \hideinitializer */
8963 +
8964 +/**
8965 + * Specifies if the uIP ARP module should be compiled with a fixed
8966 + * Ethernet MAC address or not.
8967 + *
8968 + * If this configuration option is 0, the macro uip_setethaddr() can
8969 + * be used to specify the Ethernet address at run-time.
8970 + *
8971 + * \hideinitializer
8972 + */
8973 +#define UIP_FIXEDETHADDR 0
8974 +
8975 +#define UIP_ETHADDR0 0x00 /**< The first octet of the Ethernet
8976 + address if UIP_FIXEDETHADDR is
8977 + 1. \hideinitializer */
8978 +#define UIP_ETHADDR1 0xbd /**< The second octet of the Ethernet
8979 + address if UIP_FIXEDETHADDR is
8980 + 1. \hideinitializer */
8981 +#define UIP_ETHADDR2 0x3b /**< The third octet of the Ethernet
8982 + address if UIP_FIXEDETHADDR is
8983 + 1. \hideinitializer */
8984 +#define UIP_ETHADDR3 0x33 /**< The fourth octet of the Ethernet
8985 + address if UIP_FIXEDETHADDR is
8986 + 1. \hideinitializer */
8987 +#define UIP_ETHADDR4 0x05 /**< The fifth octet of the Ethernet
8988 + address if UIP_FIXEDETHADDR is
8989 + 1. \hideinitializer */
8990 +#define UIP_ETHADDR5 0x71 /**< The sixth octet of the Ethernet
8991 + address if UIP_FIXEDETHADDR is
8992 + 1. \hideinitializer */
8993 +
8994 +/** @} */
8995 +/*------------------------------------------------------------------------------*/
8996 +/**
8997 + * \defgroup uipoptip IP configuration options
8998 + * @{
8999 + *
9000 + */
9001 +/**
9002 + * The IP TTL (time to live) of IP packets sent by uIP.
9003 + *
9004 + * This should normally not be changed.
9005 + */
9006 +#define UIP_TTL 255
9007 +
9008 +/**
9009 + * Turn on support for IP packet reassembly.
9010 + *
9011 + * uIP supports reassembly of fragmented IP packets. This features
9012 + * requires an additonal amount of RAM to hold the reassembly buffer
9013 + * and the reassembly code size is approximately 700 bytes. The
9014 + * reassembly buffer is of the same size as the uip_buf buffer
9015 + * (configured by UIP_BUFSIZE).
9016 + *
9017 + * \note IP packet reassembly is not heavily tested.
9018 + *
9019 + * \hideinitializer
9020 + */
9021 +#define UIP_REASSEMBLY 0
9022 +
9023 +/**
9024 + * The maximum time an IP fragment should wait in the reassembly
9025 + * buffer before it is dropped.
9026 + *
9027 + */
9028 +#define UIP_REASS_MAXAGE 40
9029 +
9030 +/** @} */
9031 +
9032 +/*------------------------------------------------------------------------------*/
9033 +/**
9034 + * \defgroup uipoptudp UDP configuration options
9035 + * @{
9036 + *
9037 + * \note The UDP support in uIP is still not entirely complete; there
9038 + * is no support for sending or receiving broadcast or multicast
9039 + * packets, but it works well enough to support a number of vital
9040 + * applications such as DNS queries, though
9041 + */
9042 +
9043 +/**
9044 + * Toggles wether UDP support should be compiled in or not.
9045 + *
9046 + * \hideinitializer
9047 + */
9048 +#define UIP_UDP 0
9049 +
9050 +/**
9051 + * Toggles if UDP checksums should be used or not.
9052 + *
9053 + * \note Support for UDP checksums is currently not included in uIP,
9054 + * so this option has no function.
9055 + *
9056 + * \hideinitializer
9057 + */
9058 +#define UIP_UDP_CHECKSUMS 0
9059 +
9060 +/**
9061 + * The maximum amount of concurrent UDP connections.
9062 + *
9063 + * \hideinitializer
9064 + */
9065 +#define UIP_UDP_CONNS 10
9066 +
9067 +/**
9068 + * The name of the function that should be called when UDP datagrams arrive.
9069 + *
9070 + * \hideinitializer
9071 + */
9072 +#define UIP_UDP_APPCALL udp_appcall
9073 +
9074 +/** @} */
9075 +/*------------------------------------------------------------------------------*/
9076 +/**
9077 + * \defgroup uipopttcp TCP configuration options
9078 + * @{
9079 + */
9080 +
9081 +/**
9082 + * Determines if support for opening connections from uIP should be
9083 + * compiled in.
9084 + *
9085 + * If the applications that are running on top of uIP for this project
9086 + * do not need to open outgoing TCP connections, this configration
9087 + * option can be turned off to reduce the code size of uIP.
9088 + *
9089 + * \hideinitializer
9090 + */
9091 +#define UIP_ACTIVE_OPEN 1
9092 +
9093 +/**
9094 + * The maximum number of simultaneously open TCP connections.
9095 + *
9096 + * Since the TCP connections are statically allocated, turning this
9097 + * configuration knob down results in less RAM used. Each TCP
9098 + * connection requires approximatly 30 bytes of memory.
9099 + *
9100 + * \hideinitializer
9101 + */
9102 +#define UIP_CONNS 10
9103 +
9104 +/**
9105 + * The maximum number of simultaneously listening TCP ports.
9106 + *
9107 + * Each listening TCP port requires 2 bytes of memory.
9108 + *
9109 + * \hideinitializer
9110 + */
9111 +#define UIP_LISTENPORTS 10
9112 +
9113 +/**
9114 + * The size of the advertised receiver's window.
9115 + *
9116 + * Should be set low (i.e., to the size of the uip_buf buffer) is the
9117 + * application is slow to process incoming data, or high (32768 bytes)
9118 + * if the application processes data quickly.
9119 + *
9120 + * \hideinitializer
9121 + */
9122 +#define UIP_RECEIVE_WINDOW 32768
9123 +
9124 +/**
9125 + * Determines if support for TCP urgent data notification should be
9126 + * compiled in.
9127 + *
9128 + * Urgent data (out-of-band data) is a rarely used TCP feature that
9129 + * very seldom would be required.
9130 + *
9131 + * \hideinitializer
9132 + */
9133 +#define UIP_URGDATA 1
9134 +
9135 +/**
9136 + * The initial retransmission timeout counted in timer pulses.
9137 + *
9138 + * This should not be changed.
9139 + */
9140 +#define UIP_RTO 3
9141 +
9142 +/**
9143 + * The maximum number of times a segment should be retransmitted
9144 + * before the connection should be aborted.
9145 + *
9146 + * This should not be changed.
9147 + */
9148 +#define UIP_MAXRTX 8
9149 +
9150 +/**
9151 + * The maximum number of times a SYN segment should be retransmitted
9152 + * before a connection request should be deemed to have been
9153 + * unsuccessful.
9154 + *
9155 + * This should not need to be changed.
9156 + */
9157 +#define UIP_MAXSYNRTX 3
9158 +
9159 +/**
9160 + * The TCP maximum segment size.
9161 + *
9162 + * This is should not be to set to more than UIP_BUFSIZE - UIP_LLH_LEN - 40.
9163 + */
9164 +#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - 40)
9165 +
9166 +/**
9167 + * How long a connection should stay in the TIME_WAIT state.
9168 + *
9169 + * This configiration option has no real implication, and it should be
9170 + * left untouched.
9171 + */
9172 +#define UIP_TIME_WAIT_TIMEOUT 120
9173 +
9174 +
9175 +/** @} */
9176 +/*------------------------------------------------------------------------------*/
9177 +/**
9178 + * \defgroup uipoptarp ARP configuration options
9179 + * @{
9180 + */
9181 +
9182 +/**
9183 + * The size of the ARP table.
9184 + *
9185 + * This option should be set to a larger value if this uIP node will
9186 + * have many connections from the local network.
9187 + *
9188 + * \hideinitializer
9189 + */
9190 +#define UIP_ARPTAB_SIZE 8
9191 +
9192 +/**
9193 + * The maxium age of ARP table entries measured in 10ths of seconds.
9194 + *
9195 + * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
9196 + * default).
9197 + */
9198 +#define UIP_ARP_MAXAGE 120
9199 +
9200 +/** @} */
9201 +
9202 +/*------------------------------------------------------------------------------*/
9203 +
9204 +/**
9205 + * \defgroup uipoptgeneral General configuration options
9206 + * @{
9207 + */
9208 +
9209 +/**
9210 + * The size of the uIP packet buffer.
9211 + *
9212 + * The uIP packet buffer should not be smaller than 60 bytes, and does
9213 + * not need to be larger than 1500 bytes. Lower size results in lower
9214 + * TCP throughput, larger size results in higher TCP throughput.
9215 + *
9216 + * \hideinitializer
9217 + */
9218 +#define UIP_BUFSIZE 1500
9219 +
9220 +
9221 +/**
9222 + * Determines if statistics support should be compiled in.
9223 + *
9224 + * The statistics is useful for debugging and to show the user.
9225 + *
9226 + * \hideinitializer
9227 + */
9228 +#define UIP_STATISTICS 1
9229 +
9230 +/**
9231 + * Determines if logging of certain events should be compiled in.
9232 + *
9233 + * This is useful mostly for debugging. The function uip_log()
9234 + * must be implemented to suit the architecture of the project, if
9235 + * logging is turned on.
9236 + *
9237 + * \hideinitializer
9238 + */
9239 +#define UIP_LOGGING 0
9240 +
9241 +/**
9242 + * Print out a uIP log message.
9243 + *
9244 + * This function must be implemented by the module that uses uIP, and
9245 + * is called by uIP whenever a log message is generated.
9246 + */
9247 +void uip_log(char *msg);
9248 +
9249 +/**
9250 + * The link level header length.
9251 + *
9252 + * This is the offset into the uip_buf where the IP header can be
9253 + * found. For Ethernet, this should be set to 14. For SLIP, this
9254 + * should be set to 0.
9255 + *
9256 + * \hideinitializer
9257 + */
9258 +#define UIP_LLH_LEN 14
9259 +
9260 +
9261 +/** @} */
9262 +/*------------------------------------------------------------------------------*/
9263 +/**
9264 + * \defgroup uipoptcpu CPU architecture configuration
9265 + * @{
9266 + *
9267 + * The CPU architecture configuration is where the endianess of the
9268 + * CPU on which uIP is to be run is specified. Most CPUs today are
9269 + * little endian, and the most notable exception are the Motorolas
9270 + * which are big endian. The BYTE_ORDER macro should be changed to
9271 + * reflect the CPU architecture on which uIP is to be run.
9272 + */
9273 +#ifndef LITTLE_ENDIAN
9274 +#define LITTLE_ENDIAN 3412
9275 +#endif /* LITTLE_ENDIAN */
9276 +#ifndef BIG_ENDIAN
9277 +#define BIG_ENDIAN 1234
9278 +#endif /* BIGE_ENDIAN */
9279 +
9280 +/**
9281 + * The byte order of the CPU architecture on which uIP is to be run.
9282 + *
9283 + * This option can be either BIG_ENDIAN (Motorola byte order) or
9284 + * LITTLE_ENDIAN (Intel byte order).
9285 + *
9286 + * \hideinitializer
9287 + */
9288 +/*#ifndef BYTE_ORDER*/
9289 +#define BYTE_ORDER BIG_ENDIAN
9290 +/*#endif*/ /* BYTE_ORDER */
9291 +
9292 +/** @} */
9293 +/*------------------------------------------------------------------------------*/
9294 +
9295 +/**
9296 + * \defgroup uipoptapp Appication specific configurations
9297 + * @{
9298 + *
9299 + * An uIP application is implemented using a single application
9300 + * function that is called by uIP whenever a TCP/IP event occurs. The
9301 + * name of this function must be registered with uIP at compile time
9302 + * using the UIP_APPCALL definition.
9303 + *
9304 + * uIP applications can store the application state within the
9305 + * uip_conn structure by specifying the size of the application
9306 + * structure with the UIP_APPSTATE_SIZE macro.
9307 + *
9308 + * The file containing the definitions must be included in the
9309 + * uipopt.h file.
9310 + *
9311 + * The following example illustrates how this can look.
9312 + \code
9313 +
9314 +void httpd_appcall(void);
9315 +#define UIP_APPCALL httpd_appcall
9316 +
9317 +struct httpd_state {
9318 + u8_t state;
9319 + u16_t count;
9320 + char *dataptr;
9321 + char *script;
9322 +};
9323 +#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
9324 + \endcode
9325 + */
9326 +
9327 +/**
9328 + * \var #define UIP_APPCALL
9329 + *
9330 + * The name of the application function that uIP should call in
9331 + * response to TCP/IP events.
9332 + *
9333 + */
9334 +
9335 +/**
9336 + * \var #define UIP_APPSTATE_SIZE
9337 + *
9338 + * The size of the application state that is to be stored in the
9339 + * uip_conn structure.
9340 + */
9341 +/** @} */
9342 +
9343 +/* Include the header file for the application program that should be
9344 + used. If you don't use the example web server, you should change
9345 + this. */
9346 +#include "httpd.h"
9347 +
9348 +
9349 +#endif /* __UIPOPT_H__ */