3 @@ -43,6 +43,18 @@ U_BOOT_CMD(
4 "[loadAddress] [[hostIPaddr:]bootfilename]"
7 +#if defined(CONFIG_CMD_HTTPD)
8 +int do_httpd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
10 + return NetLoopHttpd();
14 + httpd, 1, 1, do_httpd,
15 + "httpd\t- start webserver", ""
19 int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
21 return netboot_common (TFTP, cmdtp, argc, argv);
25 +#ifndef _UIP_HTTPD_H__
26 +#define _UIP_HTTPD_H__
28 +void HttpdStart (void);
29 +void HttpdHandler (void);
31 +/* board specific implementation */
32 +extern int do_http_upgrade(const unsigned char *data, const ulong size);
34 +#define HTTP_PROGRESS_START 0
35 +#define HTTP_PROGRESS_TIMEOUT 1
36 +#define HTTP_PROGRESS_UPLOAD_READY 2
37 +#define HTTP_PROGRESS_UGRADE_READY 3
38 +#define HTTP_PROGRESS_UGRADE_FAILED 4
39 +extern int do_http_progress(const int state);
44 @@ -383,7 +383,8 @@ extern int NetTimeOffset; /* offset ti
46 /* Initialize the network adapter */
47 extern int NetLoop(proto_t);
49 +extern int NetLoopHttpd(void);
50 +extern void NetSendHttpd(void);
51 /* Shutdown adapters and cleanup */
52 extern void NetStop(void);
56 @@ -26,6 +26,10 @@ include $(TOPDIR)/config.mk
62 +$(shell mkdir -p $(obj)$(UIPDIR))
63 +$(shell mkdir -p $(obj)$(RSADIR))
65 COBJS-$(CONFIG_CMD_NET) += bootp.o
66 COBJS-$(CONFIG_CMD_DNS) += dns.o
67 @@ -36,6 +40,9 @@ COBJS-$(CONFIG_CMD_NET) += rarp.o
68 COBJS-$(CONFIG_CMD_SNTP) += sntp.o
69 COBJS-$(CONFIG_CMD_NET) += tftp.o
71 +COBJS-$(CONFIG_CMD_HTTPD) += httpd.o $(UIPDIR)/fs.o $(UIPDIR)/httpd.o $(UIPDIR)/uip_arp.o $(UIPDIR)/uip_arch.o $(UIPDIR)/uip.o
72 +COBJS-$(CONFIG_CMD_RSA) += $(RSADIR)/bigint.o $(RSADIR)/base64.o $(RSADIR)/rmd160.o $(RSADIR)/rsa.o
75 SRCS := $(COBJS:.o=.c)
76 OBJS := $(addprefix $(obj),$(COBJS))
81 + * Copyright 1994, 1995, 2000 Neil Russell.
83 + * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
89 +#include "uip-0.9/uipopt.h"
90 +#include "uip-0.9/uip.h"
91 +#include "uip-0.9/uip_arp.h"
94 +#if defined(CONFIG_CMD_HTTPD)
98 +static int arptimer = 0;
104 + for(i = 0; i < UIP_CONNS; i++) {
111 + if(++arptimer == 20) {
121 + NetSetTimeout (TIMEOUT * 1000, HttpdTimeout);
135 #if defined(CONFIG_CMD_DNS)
138 +#if defined(CONFIG_CMD_HTTPD)
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[]);
152 DECLARE_GLOBAL_DATA_PTR;
154 @@ -1308,6 +1321,13 @@ NetReceive(volatile uchar * inpkt, int l
156 debug("packet received\n");
158 +#if defined(CONFIG_CMD_HTTPD)
159 + if(https_running) {
160 + NetReceiveHttpd(inpkt, len);
166 NetRxPacketLen = len;
167 et = (Ethernet_t *)inpkt;
168 @@ -1922,3 +1942,162 @@ ushort getenv_VLAN(char *var)
170 return (string_to_VLAN(getenv(var)));
173 +#if defined(CONFIG_CMD_HTTPD)
178 + volatile uchar *tmpbuf = NetTxPacket;
181 + for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
182 + tmpbuf[i] = uip_buf[i];
185 + for(; i < uip_len; i++) {
186 + tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
188 + eth_send(NetTxPacket, uip_len);
191 +#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
194 +NetReceiveHttpd(volatile uchar * inpkt, int len)
196 + memcpy(uip_buf, inpkt, len);
198 + if(BUF->type == htons(UIP_ETHTYPE_IP)) {
205 + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
216 + unsigned long long tout = 0;
218 + unsigned short int ip[2];
220 +#ifdef CONFIG_NET_MULTI
225 + /* XXX problem with bss workaround */
226 + NetArpWaitPacketMAC = NULL;
227 + NetArpWaitTxPacket = NULL;
228 + NetArpWaitPacketIP = 0;
229 + NetArpWaitReplyIP = 0;
230 + NetArpWaitTxPacket = NULL;
231 + NetTxPacket = NULL;
234 + if (!NetTxPacket) {
237 + * Setup packet buffers, aligned correctly.
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;
246 + if (!NetArpWaitTxPacket) {
247 + NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
248 + NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
249 + NetArpWaitTxPacketSize = 0;
255 +#ifdef CONFIG_NET_MULTI
258 + if (eth_init(bd) < 0) {
263 +#ifdef CONFIG_NET_MULTI
264 + memcpy (NetOurEther, eth_get_dev()->enetaddr, 6);
266 + eth_getenv_enetaddr("ethaddr", NetOurEther);
269 + NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
270 + NetOurGatewayIP = getenv_IPaddr ("gatewayip");
271 + NetOurSubnetMask= getenv_IPaddr ("netmask");
272 + NetOurVLAN = getenv_VLAN("vlan");
273 + NetOurNativeVLAN = getenv_VLAN("nvlan");
275 + printf("starting httpd server from server %ld.%ld.%ld.%ld\n",
276 + (bd->bi_ip_addr & 0xff000000) >> 24,
277 + (bd->bi_ip_addr & 0x00ff0000) >> 16,
278 + (bd->bi_ip_addr & 0x0000ff00) >> 8,
279 + (bd->bi_ip_addr & 0x000000ff));
283 + ip[0] = ((bd->bi_ip_addr & 0xffff0000) >> 16);
284 + ip[1] = (bd->bi_ip_addr & 0x0000ffff);
285 + uip_sethostaddr(ip);
287 + do_http_progress(HTTP_PROGRESS_START);
291 + unsigned long long t1;
297 + if(t1 - tout > 1000) {
298 + do_http_progress(HTTP_PROGRESS_TIMEOUT);
302 + if(!httpd_upload_complete)
304 + printf("Bytes transferred = %ld (%lx hex)\n",
305 + NetBootFileXferSize,
306 + NetBootFileXferSize);
308 + do_http_progress(HTTP_PROGRESS_UPLOAD_READY);
309 + if(do_http_upgrade(&httpd_upload_data[0], NetBootFileXferSize) == 0) {
310 + do_http_progress(HTTP_PROGRESS_UGRADE_READY);
312 + do_reset (0,0,0,0);
318 + NetBootFileXferSize = 0;
319 + httpd_upload_complete = 0;
320 + upload_running = 0;
321 +// free(httpd_upload_data);
323 + do_http_progress(HTTP_PROGRESS_UGRADE_FAILED);
332 +++ b/net/rsa/Makefile
335 +# FONRSA & FONSIGN libraries unit testing
337 +# This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
339 +# Execute in this directory
341 +# Created: 20070422 Pablo Martin Medrano <pablo@fon.com>
343 +# $Id: Makefile 389 2007-06-11 08:29:56Z pablo.martin $
345 +# FIXME: Put this in the main Makefile.am
347 +all: fonsign dump_key
350 + gcc -g sign_openssl.c -D__MAINTEST__ -o fonsign -lssl
353 + gcc -o dump_key dump_key.c
354 + ./dump_key > public_key.h
357 + gcc -g bigint.c fonrsa.c rmd160.c foncheckrsa.c base64.c log.c -o foncheckrsa
359 +#private_fon_rsa_key.pem:
360 +# openssl genrsa -out private_fon_rsa_key.pem 4096
361 +# openssl rsa -in private_fon_rsa_key.pem -pubout -out public_fon_rsa_key.pem
364 + rm fonsign dump_key
366 +++ b/net/rsa/base64.c
370 +static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
371 +/* Note that '=' (padding) is 0 */
372 +static const unsigned char fb64[256] = {
373 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
374 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
375 + 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
376 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
377 + 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
378 + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
379 + 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
380 + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
381 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
382 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
383 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
384 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
385 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
386 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
387 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
388 + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
391 +static int encodeblock( unsigned char *in, char *out, int len )
396 + for (i = 0; i < len; i++)
398 + for (i = len; i < 3; i++)
400 + out[0] = (unsigned char)(cb64[(s[0] & 0xfc) >> 2 ]);
401 + out[1] = (unsigned char)(cb64[((s[0] & 0x03) << 4) | ((s[1] & 0xf0) >> 4) ]);
402 + out[2] = (unsigned char)(cb64[((s[1] & 0x0f) << 2) | ((s[2] & 0xc0) >> 6) ]);
403 + out[3] = (unsigned char)(cb64[s[2] & 0x3f ]);
417 +static int decodeblock(char *ins, unsigned char *out, int len)
420 + unsigned char in[4];
425 + for (i = 0; i < len; i++) {
426 + if (ins[i] == '=') {
430 + in[i] = fb64[(int)(ins[i])];
431 + if (in[i] == 255) {
435 + out[0] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
439 + out[1] = (unsigned char )((in[1] & 0x0f) << 4 | in[2] >> 2);
443 + out[2] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
448 +int B64_encode(char *source, char *destination, int size_source, int size_destination)
450 + int chunks, reminder, size, d, i, size_expected;
454 + chunks = size_source / 3;
455 + reminder = size_source % 3;
457 + size_expected = (chunks * 4) + (reminder?(reminder + 1):0);
458 + if (size_destination < ((chunks * 4) + (reminder?4:0))) {
461 + for (i = 0; i < chunks; i++) {
462 + s = source + (i * 3);
463 + t = destination + (i * 4);
464 + d = encodeblock(s, t, 3);
471 + d = encodeblock(source + (chunks * 3), destination + (chunks * 4), reminder);
480 +int B64_decode(char *source, char *destination, int size_source, int size_destination)
482 + int chunks, reminder, size, d, i;
484 + chunks = size_source / 4;
485 + reminder = size_source % 4;
490 + if (size_destination < ((chunks * 3))) {
492 + size_destination, ((chunks * 3) + reminder));
495 + for (i = 0; i < chunks; i++) {
496 + d = decodeblock(source + (i * 4), destination + (i * 3), 4);
506 +++ b/net/rsa/base64.h
513 +int B64_encode(char *source, char *destination, int size_source, int size_destination);
514 +int B64_decode(char *source, char *destination, int size_source, int size_destination);
520 +++ b/net/rsa/bigint.c
523 + * Copyright(C) 2006
525 + * This library is free software; you can redistribute it and/or modify
526 + * it under the terms of the GNU Lesser General Public License as published by
527 + * the Free Software Foundation; either version 2.1 of the License, or
528 + * (at your option) any later version.
530 + * This library is distributed in the hope that it will be useful,
531 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
532 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
533 + * GNU Lesser General Public License for more details.
535 + * You should have received a copy of the GNU Lesser General Public License
536 + * along with this library; if not, write to the Free Software
537 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
541 + * @defgroup bigint_api Big Integer API
542 + * @brief The bigint implementation as used by the axTLS project.
544 + * The bigint library is for RSA encryption/decryption as well as signing.
545 + * This code tries to minimise use of malloc/free by maintaining a small
546 + * cache. A bigint context may maintain state by being made "permanent".
547 + * It be be later released with a bi_depermanent() and bi_free() call.
549 + * It supports the following reduction techniques:
554 + * It also implements the following:
555 + * - Karatsuba multiplication
557 + * - Sliding window exponentiation
558 + * - Chinese Remainder Theorem (implemented in rsa.c).
560 + * All the algorithms used are pretty standard, and designed for different
561 + * data bus sizes. Negative numbers are not dealt with at all, so a subtraction
562 + * may need to be tested for negativity.
564 + * This library steals some ideas from Jef Poskanzer
565 + * <http://cs.marlboro.edu/term/cs-fall02/algorithms/crypto/RSA/bigint>
566 + * and GMP <http://www.swox.com/gmp>. It gets most of its implementation
567 + * detail from "The Handbook of Applied Cryptography"
568 + * <http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf>
576 +static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bi, comp i);
577 +static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom);
578 +static bigint *alloc(BI_CTX *ctx, int size);
579 +static bigint *trim(bigint *bi);
580 +static void more_comps(bigint *bi, int n);
583 + * @brief Start a new bigint context.
584 + * @return A bigint context.
586 +BI_CTX *bi_initialize(void)
588 + BI_CTX *ctx = (BI_CTX *)calloc(1, sizeof(BI_CTX));
590 + ctx->active_list = NULL;
591 + ctx->active_count = 0;
592 + ctx->free_list = NULL;
593 + ctx->free_count = 0;
594 + ctx->mod_offset = 0;
597 + ctx->bi_radix = alloc(ctx, 2);
598 + ctx->bi_radix->comps[0] = 0;
599 + ctx->bi_radix->comps[1] = 1;
600 + bi_permanent(ctx->bi_radix);
606 + * @brief Close the bigint context and free any resources.
608 + * Free up any used memory - a check is done if all objects were not
610 + * @param ctx [in] The bigint session context.
612 +void bi_terminate(BI_CTX *ctx)
616 + bi_depermanent(ctx->bi_radix);
617 + bi_free(ctx, ctx->bi_radix);
619 + if (ctx->active_count != 0)
621 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
622 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
623 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
624 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
625 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
626 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
630 + for (p = ctx->free_list; p != NULL; p = pn)
641 + * @brief Increment the number of references to this object.
642 + * It does not do a full copy.
643 + * @param bi [in] The bigint to copy.
644 + * @return A referent to the same bigint.
646 +bigint *bi_copy(bigint *bi)
649 + if (bi->refs != PERMANENT)
655 + * @brief Simply make a bigint object "unfreeable" if bi_free() is called on it.
657 + * For this object to be freed, bi_depermanent() must be called.
658 + * @param bi [in] The bigint to be made permanent.
660 +void bi_permanent(bigint *bi)
665 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
666 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
667 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
671 + bi->refs = PERMANENT;
675 + * @brief Take a permanent object and make it elligible for freedom.
676 + * @param bi [in] The bigint to be made back to temporary.
678 +void bi_depermanent(bigint *bi)
681 + if (bi->refs != PERMANENT)
683 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
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__);
694 + * @brief Free a bigint object so it can be used again.
696 + * The memory itself it not actually freed, just tagged as being available
697 + * @param ctx [in] The bigint session context.
698 + * @param bi [in] The bigint to be freed.
700 +void bi_free(BI_CTX *ctx, bigint *bi)
703 + if (bi->refs == PERMANENT)
708 + if (--bi->refs > 0)
713 + bi->next = ctx->free_list;
714 + ctx->free_list = bi;
717 + if (--ctx->active_count < 0)
719 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
720 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
721 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
722 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
728 + * @brief Convert an (unsigned) integer into a bigint.
729 + * @param ctx [in] The bigint session context.
730 + * @param i [in] The (unsigned) integer to be converted.
733 +bigint *int_to_bi(BI_CTX *ctx, comp i)
735 + bigint *biR = alloc(ctx, 1);
741 + * @brief Do a full copy of the bigint object.
742 + * @param ctx [in] The bigint session context.
743 + * @param bi [in] The bigint object to be copied.
745 +bigint *bi_clone(BI_CTX *ctx, const bigint *bi)
747 + bigint *biR = alloc(ctx, bi->size);
749 + memcpy(biR->comps, bi->comps, bi->size*COMP_BYTE_SIZE);
754 + * @brief Perform an additon operation between two bigints.
755 + * @param ctx [in] The bigint session context.
756 + * @param bia [in] A bigint.
757 + * @param bib [in] Another bigint.
758 + * @return The result of the addition.
760 +bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib)
769 + if (bia->size > bib->size)
773 + more_comps(bia, n+1);
774 + more_comps(bib, n);
784 + carry = cy1 | (rl < sl);
786 + } while (--n != 0);
788 + *pa = carry; /* do overflow */
794 + * @brief Perform a subtraction operation between two bigints.
795 + * @param ctx [in] The bigint session context.
796 + * @param bia [in] A bigint.
797 + * @param bib [in] Another bigint.
798 + * @param is_negative [out] If defined, indicates that the result was negative.
799 + * is_negative may be NULL.
800 + * @return The result of the subtraction. The result is always positive.
802 +bigint *bi_subtract(BI_CTX *ctx,
803 + bigint *bia, bigint *bib, int *is_negative)
806 + comp *pa, *pb, carry = 0;
811 + more_comps(bib, n);
821 + carry = cy1 | (rl > sl);
823 + } while (--n != 0);
825 + if (is_negative) /* indicate a negative result */
827 + *is_negative = carry;
830 + bi_free(ctx, trim(bib)); /* put bib back to the way it was */
835 + * Perform a multiply between a bigint an an (unsigned) integer
837 +static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b)
839 + int j = 0, n = bia->size;
840 + bigint *biR = alloc(ctx, n + 1);
842 + comp *r = biR->comps;
843 + comp *a = bia->comps;
847 + /* clear things to start with */
848 + memset(r, 0, ((n+1)*COMP_BYTE_SIZE));
852 + long_comp tmp = *r + (long_comp)a[j]*b + carry;
853 + *r++ = (comp)tmp; /* downsize */
854 + carry = (comp)(tmp >> COMP_BIT_SIZE);
863 + * @brief Does both division and modulo calculations.
865 + * Used extensively when doing classical reduction.
866 + * @param ctx [in] The bigint session context.
867 + * @param u [in] A bigint which is the numerator.
868 + * @param v [in] Either the denominator or the modulus depending on the mode.
869 + * @param is_mod [n] Determines if this is a normal division (0) or a reduction
871 + * @return The result of the division/reduction.
873 +bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
875 + int n = v->size, m = u->size-n;
876 + int j = 0, orig_u_size = u->size;
877 + uint8_t mod_offset = ctx->mod_offset;
879 + bigint *quotient, *tmp_u;
885 + /* if doing reduction and we are < mod, then return mod */
886 + if (is_mod && bi_compare(v, u) > 0)
892 + quotient = alloc(ctx, m+1);
893 + tmp_u = alloc(ctx, n+1);
894 + v = trim(v); /* make sure we have no leading 0's */
895 + // d = (comp)((long_comp)COMP_RADIX/(V1+1));
896 + long_comp x = COMP_RADIX; do_div(x, V1+1); d = x;
898 + /* clear things to start with */
899 + memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE));
904 + u = bi_int_multiply(ctx, u, d);
908 + v = ctx->bi_normalised_mod[mod_offset];
912 + v = bi_int_multiply(ctx, v, d);
916 + if (orig_u_size == u->size) /* new digit position u0 */
918 + more_comps(u, orig_u_size + 1);
923 + /* get a temporary short version of u */
924 + memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE);
929 + q_dash = COMP_RADIX-1;
933 + //q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1);
934 + long_comp x = U(0)*COMP_RADIX + U(1); do_div(x, V1); q_dash = x;
938 + if (v->size > 1 && V2)
940 + /* we are implementing the following
941 + if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) -
942 + q_dash*V1)*COMP_RADIX) + U(2))) ... */
943 + comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) -
944 + (long_comp)q_dash*V1);
945 + if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2))
951 + /* multiply and subtract */
955 + tmp_u = bi_subtract(ctx, tmp_u,
956 + bi_int_multiply(ctx, bi_copy(v), q_dash), &is_negative);
957 + more_comps(tmp_u, n+1);
965 + tmp_u = bi_add(ctx, tmp_u, bi_copy(v));
966 + /* lop off the carry */
976 + /* copy back to u */
977 + memcpy(&u->comps[u->size-n-1-j], tmp_u->comps, (n+1)*COMP_BYTE_SIZE);
978 + } while (++j <= m);
980 + bi_free(ctx, tmp_u);
983 + if (is_mod) /* get the remainder */
985 + bi_free(ctx, quotient);
986 + return bi_int_divide(ctx, trim(u), d);
988 + else /* get the quotient */
991 + return trim(quotient);
996 + * Perform an integer divide on a bigint.
998 +static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom)
1000 + int i = biR->size - 1;
1007 + r = (r<<COMP_BIT_SIZE) + biR->comps[i];
1008 + //biR->comps[i] = (comp)(r / denom);
1009 + long_comp x = r; do_div(x, denom); biR->comps[i] = x;
1010 +/* while(r > denom)
1015 + } while (--i != 0);
1021 + * @brief Allow a binary sequence to be imported as a bigint.
1022 + * @param ctx [in] The bigint session context.
1023 + * @param data [in] The data to be converted.
1024 + * @param size [in] The number of bytes of data.
1025 + * @return A bigint representing this data.
1027 +bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int size)
1029 + bigint *biR = alloc(ctx, (size+COMP_BYTE_SIZE-1)/COMP_BYTE_SIZE);
1030 + int i, j = 0, offset = 0;
1032 + memset(biR->comps, 0, biR->size*COMP_BYTE_SIZE);
1034 + for (i = size-1; i >= 0; i--)
1036 + biR->comps[offset] += data[i] << (j*8);
1038 + if (++j == COMP_BYTE_SIZE)
1049 + * @brief Take a bigint and convert it into a byte sequence.
1051 + * This is useful after a decrypt operation.
1052 + * @param ctx [in] The bigint session context.
1053 + * @param x [in] The bigint to be converted.
1054 + * @param data [out] The converted data as a byte stream.
1055 + * @param size [in] The maximum size of the byte stream. Unused bytes will be
1058 +void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
1060 + int i, j, k = size-1;
1063 + memset(data, 0, size); /* ensure all leading 0's are cleared */
1065 + for (i = 0; i < x->size; i++)
1067 + for (j = 0; j < COMP_BYTE_SIZE; j++)
1069 + comp mask = 0xff << (j*8);
1070 + int num = (x->comps[i] & mask) >> (j*8);
1084 + * @brief Pre-calculate some of the expensive steps in reduction.
1086 + * This function should only be called once (normally when a session starts).
1087 + * When the session is over, bi_free_mod() should be called. bi_mod_power()
1088 + * relies on this function being called.
1089 + * @param ctx [in] The bigint session context.
1090 + * @param bim [in] The bigint modulus that will be used.
1091 + * @param mod_offset [in] There are three moduluii that can be stored - the
1092 + * standard modulus, and it's two primes p and q. This offset refers to which
1093 + * modulus we are referring to.
1094 + * @see bi_free_mod(), bi_mod_power().
1096 +void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset)
1098 + int k = bim->size;
1100 +// comp d = (comp)((long_comp)COMP_RADIX/(bim->comps[k-1]+1));
1101 + long_comp x = COMP_RADIX; do_div(x, bim->comps[k-1]+1); d = x;
1103 + ctx->bi_mod[mod_offset] = bim;
1104 + bi_permanent(ctx->bi_mod[mod_offset]);
1105 + ctx->bi_normalised_mod[mod_offset] = bi_int_multiply(ctx, bim, d);
1106 + bi_permanent(ctx->bi_normalised_mod[mod_offset]);
1110 + * @brief Used when cleaning various bigints at the end of a session.
1111 + * @param ctx [in] The bigint session context.
1112 + * @param mod_offset [in] The offset to use.
1113 + * @see bi_set_mod().
1115 +void bi_free_mod(BI_CTX *ctx, int mod_offset)
1117 + bi_depermanent(ctx->bi_mod[mod_offset]);
1118 + bi_free(ctx, ctx->bi_mod[mod_offset]);
1119 + bi_depermanent(ctx->bi_normalised_mod[mod_offset]);
1120 + bi_free(ctx, ctx->bi_normalised_mod[mod_offset]);
1124 + * Perform a standard multiplication between two bigints.
1126 +static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
1128 + int i, j, i_plus_j, n = bia->size, t = bib->size;
1129 + bigint *biR = alloc(ctx, n + t);
1130 + comp *sr = biR->comps;
1131 + comp *sa = bia->comps;
1132 + comp *sb = bib->comps;
1137 + /* clear things to start with */
1138 + memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE));
1150 + long_comp tmp = sr[i_plus_j] + (long_comp)sa[j]*b + carry;
1151 + sr[i_plus_j++] = (comp)tmp; /* downsize */
1152 + carry = (comp)(tmp >> COMP_BIT_SIZE);
1153 + } while (++j < n);
1155 + sr[i_plus_j] = carry;
1156 + } while (++i < t);
1158 + bi_free(ctx, bia);
1159 + bi_free(ctx, bib);
1164 + * @brief Perform a multiplication operation between two bigints.
1165 + * @param ctx [in] The bigint session context.
1166 + * @param bia [in] A bigint.
1167 + * @param bib [in] Another bigint.
1168 + * @return The result of the multiplication.
1170 +bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
1175 + return regular_multiply(ctx, bia, bib);
1180 + * @brief Compare two bigints.
1181 + * @param bia [in] A bigint.
1182 + * @param bib [in] Another bigint.
1183 + * @return -1 if smaller, 1 if larger and 0 if equal.
1185 +int bi_compare(bigint *bia, bigint *bib)
1192 + if (bia->size > bib->size)
1194 + else if (bia->size < bib->size)
1198 + comp *a = bia->comps;
1199 + comp *b = bib->comps;
1201 + /* Same number of components. Compare starting from the high end
1202 + * and working down. */
1204 + i = bia->size - 1;
1213 + else if (a[i] < b[i])
1218 + } while (--i >= 0);
1225 + * Allocate and zero more components. Does not consume bi.
1227 +static void more_comps(bigint *bi, int n)
1229 + if (n > bi->max_comps)
1231 + if ((bi->max_comps * 2) > n) {
1232 + bi->max_comps = bi->max_comps * 2;
1234 + bi->max_comps = n;
1236 + bi->comps = (comp*)realloc(bi->comps, bi->max_comps * COMP_BYTE_SIZE);
1241 + memset(&bi->comps[bi->size], 0, (n-bi->size)*COMP_BYTE_SIZE);
1248 + * Make a new empty bigint. It may just use an old one if one is available.
1249 + * Otherwise get one of the heap.
1251 +static bigint *alloc(BI_CTX *ctx, int size)
1255 + /* Can we recycle an old bigint? */
1256 + if (ctx->free_list != NULL)
1258 + biR = ctx->free_list;
1259 + ctx->free_list = biR->next;
1260 + ctx->free_count--;
1261 + if (biR->refs != 0)
1263 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1264 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1265 + printf("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
1269 + more_comps(biR, size);
1273 + /* No free bigints available - create a new one. */
1274 + biR = (bigint *)malloc(sizeof(bigint));
1275 + biR->comps = (comp*) malloc(size * COMP_BYTE_SIZE);
1276 + biR->max_comps = size; /* give some space to spare */
1282 + ctx->active_count++;
1287 + * Work out the highest '1' bit in an exponent. Used when doing sliding-window
1290 +static int find_max_exp_index(bigint *biexp)
1292 + int i = COMP_BIT_SIZE-1;
1293 + comp shift = COMP_RADIX/2;
1294 + comp test = biexp->comps[biexp->size-1]; /* assume no leading zeroes */
1302 + return i+(biexp->size-1)*COMP_BIT_SIZE;
1306 + } while (--i != 0);
1308 + return -1; /* error - must have been a leading 0 */
1312 + * Is a particular bit is an exponent 1 or 0? Used when doing sliding-window
1315 +static int exp_bit_is_one(bigint *biexp, int offset)
1317 + comp test = biexp->comps[offset / COMP_BIT_SIZE];
1318 + int num_shifts = offset % COMP_BIT_SIZE;
1324 + for (i = 0; i < num_shifts; i++)
1329 + return test & shift;
1333 + * Delete any leading 0's (and allow for 0).
1335 +static bigint *trim(bigint *bi)
1339 + while (bi->comps[bi->size-1] == 0 && bi->size > 1)
1348 + * @brief Perform a modular exponentiation.
1350 + * This function requires bi_set_mod() to have been called previously. This is
1351 + * one of the optimisations used for performance.
1352 + * @param ctx [in] The bigint session context.
1353 + * @param bi [in] The bigint on which to perform the mod power operation.
1354 + * @param biexp [in] The bigint exponent.
1355 + * @see bi_set_mod().
1357 +bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
1359 + int i = find_max_exp_index(biexp), j, window_size = 1;
1360 + bigint *biR = int_to_bi(ctx, 1);
1365 + ctx->g = (bigint **)malloc(sizeof(bigint *));
1366 + ctx->g[0] = bi_clone(ctx, bi);
1368 + bi_permanent(ctx->g[0]);
1370 + /* if sliding-window is off, then only one bit will be done at a time and
1371 + * will reduce to standard left-to-right exponentiation */
1374 + if (exp_bit_is_one(biexp, i))
1376 + int l = i-window_size+1;
1379 + if (l < 0) /* LSB of exponent will always be 1 */
1385 + while (exp_bit_is_one(biexp, l) == 0)
1387 + l++; /* go back up */
1391 + /* build up the section of the exponent */
1392 + for (j = i; j >= l; j--)
1394 + biR = bi_residue(ctx, bi_square(ctx, biR));
1395 + if (exp_bit_is_one(biexp, j))
1402 + part_exp = (part_exp-1)/2; /* adjust for array */
1403 + biR = bi_residue(ctx,
1404 + bi_multiply(ctx, biR, ctx->g[part_exp]));
1407 + else /* square it */
1409 + biR = bi_residue(ctx, bi_square(ctx, biR));
1415 + for (i = 0; i < ctx->window; i++)
1417 + bi_depermanent(ctx->g[i]);
1418 + bi_free(ctx, ctx->g[i]);
1423 + bi_free(ctx, biexp);
1429 +++ b/net/rsa/bigint.h
1432 + * Copyright(C) 2006
1434 + * This library is free software; you can redistribute it and/or modify
1435 + * it under the terms of the GNU Lesser General Public License as published by
1436 + * the Free Software Foundation; either version 2 of the License, or
1437 + * (at your option) any later version.
1439 + * This library is distributed in the hope that it will be useful,
1440 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1441 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1442 + * GNU Lesser General Public License for more details.
1444 + * You should have received a copy of the GNU Lesser General Public License
1445 + * along with this library; if not, write to the Free Software
1446 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1448 + * Trimmed down from axTLS
1450 + * $Id: bigint.h 392 2007-06-25 16:24:51Z pablo.martin $
1454 +#ifndef BIGINT_HEADER
1455 +#define BIGINT_HEADER
1457 +#define CONFIG_BIGINT_CLASSICAL 1
1459 +#define SOCKET_READ(A,B,C) read(A,B,C)
1460 +#define SOCKET_WRITE(A,B,C) write(A,B,C)
1461 +#define SOCKET_CLOSE(A) close(A)
1462 +#define TTY_FLUSH()
1464 +#include "bigint_impl.h"
1466 +#ifndef CONFIG_BIGINT_CHECK_ON
1467 +#define check(A) /**< disappears in normal production mode */
1469 +BI_CTX *bi_initialize(void);
1470 +void bi_terminate(BI_CTX *ctx);
1471 +void bi_permanent(bigint *bi);
1472 +void bi_depermanent(bigint *bi);
1473 +void bi_free(BI_CTX *ctx, bigint *bi);
1474 +bigint *bi_copy(bigint *bi);
1475 +bigint *bi_clone(BI_CTX *ctx, const bigint *bi);
1476 +void bi_export(BI_CTX *ctx, bigint *bi, uint8_t *data, int size);
1477 +bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int len);
1478 +bigint *int_to_bi(BI_CTX *ctx, comp i);
1480 +/* the functions that actually do something interesting */
1481 +bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib);
1482 +bigint *bi_subtract(BI_CTX *ctx, bigint *bia,
1483 + bigint *bib, int *is_negative);
1484 +bigint *bi_divide(BI_CTX *ctx, bigint *bia, bigint *bim, int is_mod);
1485 +bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib);
1486 +bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp);
1487 +bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp);
1488 +int bi_compare(bigint *bia, bigint *bib);
1489 +void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset);
1490 +void bi_free_mod(BI_CTX *ctx, int mod_offset);
1494 + * Find the residue of B. bi_set_mod() must be called before hand.
1496 +#define bi_mod(A, B) bi_divide(A, B, ctx->bi_mod[ctx->mod_offset], 1)
1498 +#define bi_residue(A, B) bi_mod(A, B)
1500 +#define bi_square(A, B) bi_multiply(A, bi_copy(B), B)
1505 +++ b/net/rsa/bigint_impl.h
1508 + * Copyright(C) 2006
1510 + * This library is free software; you can redistribute it and/or modify
1511 + * it under the terms of the GNU Lesser General Public License as published by
1512 + * the Free Software Foundation; either version 2.1 of the License, or
1513 + * (at your option) any later version.
1515 + * This library is distributed in the hope that it will be useful,
1516 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1517 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1518 + * GNU Lesser General Public License for more details.
1520 + * You should have received a copy of the GNU Lesser General Public License
1521 + * along with this library; if not, write to the Free Software
1522 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1525 +#ifndef BIGINT_IMPL_HEADER
1526 +#define BIGINT_IMPL_HEADER
1528 +#include <linux/types.h>
1529 +#include <common.h>
1531 +/* Maintain a number of precomputed variables when doing reduction */
1532 +#define BIGINT_M_OFFSET 0 /**< Normal modulo offset. */
1533 +#ifdef CONFIG_BIGINT_CRT
1534 +#define BIGINT_P_OFFSET 1 /**< p modulo offset. */
1535 +#define BIGINT_Q_OFFSET 2 /**< q module offset. */
1536 +#define BIGINT_NUM_MODS 3 /**< The number of modulus constants used. */
1538 +#define BIGINT_NUM_MODS 1
1541 +/* Architecture specific functions for big ints */
1543 +// #define COMP_RADIX 4294967296i64
1544 +// #define COMP_BIG_MSB 0x8000000000000000i64
1546 +#define COMP_RADIX 4294967296ULL /**< Max component + 1 */
1547 +#define COMP_BIG_MSB 0x8000000000000000ULL /**< (Max dbl comp + 1)/ 2 */
1549 +#define COMP_BIT_SIZE 32 /**< Number of bits in a component. */
1550 +#define COMP_BYTE_SIZE 4 /**< Number of bytes in a component. */
1551 +#define COMP_NUM_NIBBLES 8 /**< Used For diagnostics only. */
1553 +typedef uint32_t comp; /**< A single precision component. */
1554 +typedef uint64_t long_comp; /**< A double precision component. */
1555 +typedef int64_t slong_comp; /**< A signed double precision component. */
1559 + * @brief A big integer basic object
1563 + struct _bigint* next; /**< The next bigint in the cache. */
1564 + short size; /**< The number of components in this bigint. */
1565 + short max_comps; /**< The heapsize allocated for this bigint */
1566 + int refs; /**< An internal reference count. */
1567 + comp* comps; /**< A ptr to the actual component data */
1570 +typedef struct _bigint bigint; /**< An alias for _bigint */
1573 + * Maintains the state of the cache, and a number of variables used in
1576 +typedef struct /**< A big integer "session" context. */
1578 + bigint *active_list; /**< Bigints currently used. */
1579 + bigint *free_list; /**< Bigints not used. */
1580 + bigint *bi_radix; /**< The radix used. */
1581 + bigint *bi_mod[BIGINT_NUM_MODS]; /**< modulus */
1583 +#if defined(CONFIG_BIGINT_MONTGOMERY)
1584 + bigint *bi_RR_mod_m[BIGINT_NUM_MODS]; /**< R^2 mod m */
1585 + bigint *bi_R_mod_m[BIGINT_NUM_MODS]; /**< R mod m */
1586 + comp N0_dash[BIGINT_NUM_MODS];
1587 +#elif defined(CONFIG_BIGINT_BARRETT)
1588 + bigint *bi_mu[BIGINT_NUM_MODS]; /**< Storage for mu */
1590 + bigint *bi_normalised_mod[BIGINT_NUM_MODS]; /**< Normalised mod storage. */
1591 + bigint **g; /**< Used by sliding-window. */
1592 + int window; /**< The size of the sliding window */
1594 + int active_count; /**< Number of active bigints. */
1595 + int free_count; /**< Number of free bigints. */
1597 +#ifdef CONFIG_BIGINT_MONTGOMERY
1598 + uint8_t use_classical; /**< Use classical reduction. */
1600 + uint8_t mod_offset; /**< The mod offset we are using */
1604 +#define max(a,b) ((a)>(b)?(a):(b)) /**< Find the maximum of 2 numbers. */
1605 +#define min(a,b) ((a)<(b)?(a):(b)) /**< Find the minimum of 2 numbers. */
1608 +#define PERMANENT 0x7FFF55AA /**< A magic number for permanents. */
1610 +#define V1 v->comps[v->size-1] /**< v1 for division */
1611 +#define V2 v->comps[v->size-2] /**< v2 for division */
1612 +#define U(j) tmp_u->comps[tmp_u->size-j-1] /**< uj for division */
1613 +#define Q(j) quotient->comps[quotient->size-j-1] /**< qj for division */
1617 +++ b/net/rsa/div64.h
1620 + * Copyright (C) 2000, 2004 Maciej W. Rozycki
1621 + * Copyright (C) 2003 Ralf Baechle
1623 + * This file is subject to the terms and conditions of the GNU General Public
1624 + * License. See the file "COPYING" in the main directory of this archive
1625 + * for more details.
1627 +#ifndef _ASM_DIV64_H
1628 +#define _ASM_DIV64_H
1630 +#if (_MIPS_SZLONG == 32)
1632 +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
1633 +#define GCC_REG_ACCUM "$0"
1635 +#define GCC_REG_ACCUM "accum"
1639 +//#include <asm/compiler.h>
1642 + * No traps on overflows for any of these...
1645 +#define do_div64_32(res, high, low, base) ({ \
1646 + unsigned long __quot, __mod; \
1647 + unsigned long __cf, __tmp, __tmp2, __i; \
1649 + __asm__(".set push\n\t" \
1651 + ".set noreorder\n\t" \
1652 + "move %2, $0\n\t" \
1653 + "move %3, $0\n\t" \
1655 + " li %4, 0x21\n" \
1657 + "sll $1, %0, 0x1\n\t" \
1658 + "srl %3, %0, 0x1f\n\t" \
1659 + "or %0, $1, %5\n\t" \
1660 + "sll %1, %1, 0x1\n\t" \
1661 + "sll %2, %2, 0x1\n" \
1663 + "bnez %3, 2f\n\t" \
1664 + " sltu %5, %0, %z6\n\t" \
1667 + " addiu %4, %4, -1\n\t" \
1668 + "subu %0, %0, %z6\n\t" \
1669 + "addiu %2, %2, 1\n" \
1671 + "bnez %4, 0b\n\t" \
1672 + " srl %5, %1, 0x1f\n\t" \
1674 + : "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \
1675 + "=&r" (__i), "=&r" (__tmp2) \
1676 + : "Jr" (base), "0" (high), "1" (low)); \
1681 +#define do_div(n, base) ({ \
1682 + unsigned long long __quot; \
1683 + unsigned long __mod; \
1684 + unsigned long long __div; \
1685 + unsigned long __upper, __low, __high, __base; \
1688 + __base = (base); \
1690 + __high = __div >> 32; \
1692 + __upper = __high; \
1695 + __asm__("divu $0, %z2, %z3" \
1696 + : "=h" (__upper), "=l" (__high) \
1697 + : "Jr" (__high), "Jr" (__base) \
1698 + : GCC_REG_ACCUM); \
1700 + __mod = do_div64_32(__low, __upper, __low, __base); \
1702 + __quot = __high; \
1703 + __quot = __quot << 32 | __low; \
1706 +#endif /* (_MIPS_SZLONG == 32) */
1708 +#if (_MIPS_SZLONG == 64)
1711 + * Hey, we're already 64-bit, no
1712 + * need to play games..
1714 +#define do_div(n, base) ({ \
1715 + unsigned long __quot; \
1716 + unsigned int __mod; \
1717 + unsigned long __div; \
1718 + unsigned int __base; \
1721 + __base = (base); \
1723 + __mod = __div % __base; \
1724 + __quot = __div / __base; \
1729 +#endif /* (_MIPS_SZLONG == 64) */
1731 +#endif /* _ASM_DIV64_H */
1733 +++ b/net/rsa/dump_key.c
1736 +#include <stdlib.h>
1737 +#include <sys/types.h>
1738 +#include <sys/stat.h>
1739 +#include <unistd.h>
1741 +int main(int argc, char **argv)
1743 + FILE *fp = fopen("public_fon_rsa_key_6.pem", "r");
1749 + stat("public_fon_rsa_key_6.pem", &s);
1750 + b = malloc(s.st_size);
1751 + fread(b, s.st_size, 1, fp);
1753 + printf("unsigned char public_key[] = {\n\t");
1754 + for(i = 0;i < s.st_size; i++)
1756 + printf("0x%02X,", b[i]);
1761 +// printf("\n%d %d\n", i, s.st_size);
1765 +++ b/net/rsa/foncheckrsa.c
1768 + * RSA + RIPEMD160 signature verification command
1770 + * Copyright (C) 2007 FON Wireless Ltd.
1772 + * This program is free software; you can redistribute it and/or
1773 + * modify it under the terms of the GNU General Public License
1774 + * as published by the Free Software Foundation; either version 2
1775 + * of the License, or (at your option) any later version.
1777 + * This program is distributed in the hope that it will be useful,
1778 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1779 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1780 + * GNU General Public License for more details.
1782 + * You should have received a copy of the GNU General Public License
1783 + * along with this program; if not, write to the Free Software
1784 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1786 + * Created: 20060728 Pablo MartÃn Medrano <pablo@fon.com>
1788 + * $Id: foncheckrsa.c 332 2007-05-02 09:45:54Z pablo.martin $
1791 +#include <stdlib.h>
1792 +#include <sys/types.h>
1793 +#include <sys/stat.h>
1795 +#include <string.h>
1797 +#include <unistd.h>
1798 +#include "fonrsa.h"
1800 +int main(int argc, char **argv)
1803 + FONRSA_ERROR fonrsa_error;
1807 + fprintf(stderr, " Usage: foncheckrsa [public_key.der] [signature] [file]\n");
1808 + fprintf(stderr, " Pablo MartÃn Medrano <pablo@fon.com>\n");
1809 + fprintf(stderr, " RIPEMD-160 software written by Antoon Bosselaers,\n");
1810 + fprintf(stderr, " available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.\n");
1811 + fprintf(stderr, " Uses the axTLS library bigint implementation (libfonrsa)\n");
1812 + fprintf(stderr, " http://www.leroc.com.au/axTLS/\n");
1815 + /* Check the existence of input files */
1816 + for (i = 1; i < 4; i++) {
1817 + if ((fd = open(argv[i], O_RDONLY)) == -1) {
1818 + fprintf(stderr, "Error: opening \"%s\": %s\n", argv[i],
1820 + fprintf(stderr, "Bailing out...");
1825 + handle = FR_init(argv[1]);
1826 + if (handle == NULL) {
1827 + printf("Error loading keys in %s\n", argv[1]);
1830 + fonrsa_error = FR_verify_file(handle, argv[3], argv[2]);
1832 + switch (fonrsa_error) {
1834 + printf("Verified OK\n");
1836 + case FONRSA_VERIFICATION_FAILURE:
1837 + printf("Verification failure\n");
1840 + printf("Verification error\n");
1847 +++ b/net/rsa/fonrsa.c
1850 + * FONSM RSA handling library
1852 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
1854 + * This library is free software; you can redistribute it and/or modify
1855 + * it under the terms of the GNU Lesser General Public License as published by
1856 + * the Free Software Foundation; either version 2 of the License, or
1857 + * (at your option) any later version.
1859 + * This library is distributed in the hope that it will be useful,
1860 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1861 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1862 + * GNU Lesser General Public License for more details.
1864 + * You should have received a copy of the GNU Lesser General Public License
1865 + * along with this library; if not, write to the Free Software
1866 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1868 + * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
1872 + * $Id: fonrsa.c 405 2007-09-19 15:26:17Z jesus.pico $
1874 +#include <sys/types.h>
1875 +#include <stdlib.h>
1877 +#include <string.h>
1878 +#include <sys/types.h>
1879 +#include <sys/stat.h>
1881 +#include <unistd.h>
1883 +#include "rmd160.h"
1884 +#include "bigint.h"
1885 +#include "fonrsa.h"
1886 +#include "base64.h"
1894 + bigint *m; /* modulus */
1895 + bigint *e; /* public exponent */
1897 + BI_CTX *bi_ctx; /* big integer handle */
1902 + RSA_parameters *rsaparms;
1905 +static uint8_t *CH_load_raw_file(char *filename, size_t *size);
1906 +static DER_key *CH_load_der_key(char *filename);
1907 +static void CH_free_der_key(DER_key *key);
1908 +static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters);
1909 +void CH_pub_key_new(RSA_parameters **rsa_parameters, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len);
1910 +int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out);
1911 +byte *RMDbinary(char *fname);
1912 +int CH_get_rmd160_hash_from_signature(byte *hash, char *signature_file, char *public_key_file);
1913 +static unsigned char *load_file_in_buffer(char *path, int *size);
1914 +static int save_file_from_buffer(char *path, unsigned char *buffer, int size);
1915 +int ExtractPadding(uint8_t* OutputBuffer, uint8_t* InputBuffer, int LengthOfInputBuffer);
1917 +#define RMDsize 160 /* A RIPEMD-160 hash has 160 bits */
1920 + * returns RMD(message in file fname) fname is read as binary data.
1923 +byte *RMDbinary(char *fname)
1925 + FILE *mf; /* pointer to file <fname> */
1926 + byte data[1024]; /* contains current mess. block */
1927 + dword nbytes; /* length of this block */
1928 + dword MDbuf[RMDsize / 32]; /* contains (A, B, C, D(, E)) */
1929 + static byte hashcode[RMDsize / 8]; /* for final hash-value */
1930 + dword X[16]; /* current 16-word chunk */
1931 + unsigned int i, j; /* counters */
1932 + dword length[2]; /* length in bytes of message */
1933 + dword offset; /* # of unprocessed bytes at */
1934 + /* call of MDfinish */
1937 + if ((mf = fopen(fname, "rb")) == NULL) {
1938 + fprintf(stderr, "\nRMDbinary: cannot open file \"%s\".\n",
1945 + while ((nbytes = fread(data, 1, 1024, mf)) != 0) {
1946 + /* process all complete blocks */
1947 + for (i = 0; i < (nbytes >> 6); i++) {
1948 + for (j = 0; j < 16; j++)
1949 + X[j] = BYTES_TO_DWORD(data + 64 * i + 4 * j);
1950 + compress(MDbuf, X);
1952 + /* update length[] */
1953 + if (length[0] + nbytes < length[0])
1954 + length[1]++; /* overflow to msb of length */
1955 + length[0] += nbytes;
1958 + offset = length[0] & 0x3C0; /* extract bytes 6 to 10 inclusive */
1959 + MDfinish(MDbuf, data + offset, length[0], length[1]);
1961 + for (i = 0; i < RMDsize / 8; i += 4) {
1962 + hashcode[i] = MDbuf[i >> 2];
1963 + hashcode[i + 1] = (MDbuf[i >> 2] >> 8);
1964 + hashcode[i + 2] = (MDbuf[i >> 2] >> 16);
1965 + hashcode[i + 3] = (MDbuf[i >> 2] >> 24);
1969 + return (byte *) hashcode;
1971 +byte *RMDbinary_buffer(char *buffer, int size_buffer)
1977 + * Extracts the RMD 160 hash from the signature file
1979 +int CH_get_rmd160_hash_from_signature(byte *hash, char *signature_file, char *public_key_file)
1981 + RSA_parameters *rsa_parameters;
1983 + uint8_t *signature;
1984 + size_t signature_size;
1985 + uint8_t *decrypted;
1987 + signature = CH_load_raw_file(signature_file, &signature_size);
1988 + if ((signature == NULL)||(signature_size != 512)) {
1989 + fprintf(stderr, "Error: Loading signature key '%s'\n", signature_file);
1992 + derkey = CH_load_der_key(public_key_file);
1993 + if (derkey == NULL) {
1994 + fprintf(stderr, "Error: opening DER key file '%s'\n", public_key_file);
1997 + if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
1998 + fprintf(stderr, "Error: Extracting public key from DER file\n");
2001 + CH_free_der_key(derkey);
2002 + if (rsa_parameters->num_octets != 512)
2003 + fprintf(stderr, "Error: The RSA public key size is not 4096 bits %d\n", rsa_parameters->num_octets);
2004 + decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
2005 + if (CH_decrypt(rsa_parameters, signature, decrypted)) {
2006 + fprintf(stderr, "Error: Decrypting signature\n");
2009 + memcpy(hash, decrypted + 492, 20);
2016 + * Decrypts the signature buffer using the rsa public key loaded
2018 +int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out)
2021 + bigint *decrypted_bi;
2024 + byte_size = rsa->num_octets;
2025 + dat_bi = bi_import(rsa->bi_ctx, buffer_in, byte_size);
2026 + rsa->bi_ctx->mod_offset = BIGINT_M_OFFSET;
2028 + decrypted_bi = bi_mod_power(rsa->bi_ctx, dat_bi, rsa->e);
2029 + bi_export(rsa->bi_ctx, decrypted_bi, buffer_out, byte_size);
2033 + * Loads a file in a uint8_t buffer
2035 +static uint8_t *CH_load_raw_file(char *filename, size_t *size)
2042 + if ((stat(filename, &st)) == -1)
2044 + if ((ret = (uint8_t *)malloc(st.st_size)) == NULL)
2046 + fd = open(filename, O_RDONLY);
2051 + br = read(fd, ret, st.st_size);
2053 + if (br != st.st_size) {
2057 + *size = st.st_size;
2061 + * Loads a .der file in a buffer
2063 +static DER_key *CH_load_der_key(char *filename)
2067 + if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
2069 + if ((ret->buffer = CH_load_raw_file(filename, &(ret->size))) == NULL) {
2078 +static DER_key *CH_load_pem_key(char *filename)
2087 + if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
2089 + if ((buffer = CH_load_raw_file(filename, &filesize)) == NULL) {
2093 + p = (char *)buffer;
2094 + while ((*p != '\n') && (*p != '\0'))
2102 + while((p - b64) <= filesize) {
2103 + if ((*p == '-')) {
2105 + } else if ((*p != '\n') && (*p != ' ') && (*p != '\t')) {
2112 + size = B64_decode(b64, key, strlen(b64), 1024);
2119 + ret->buffer = (char *)malloc(size);
2121 + memcpy((void *)ret->buffer, (void *)key, size);
2128 +static void CH_free_der_key(DER_key *key)
2130 + free(key->buffer);
2135 + * Get the public key specifics from an ASN.1 encoded file
2136 + * A function lacking in the exported axTLS API
2138 + * This is a really weird hack that only works with RSA public key
2141 +static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters)
2143 + uint8_t *modulus, *pub_exp;
2144 + int mod_len, pub_len;
2147 + mod_len = len - 37;
2148 + if (buf[0] != 0x30) {
2152 + pub_exp = (uint8_t *)malloc(3);
2153 + modulus = (uint8_t *)malloc(mod_len);
2154 + memcpy(modulus, buf + 32 , mod_len);
2155 + memcpy(pub_exp, buf + 34 + mod_len, 3);
2156 + if (mod_len <= 0 || pub_len <= 0 )
2158 + CH_pub_key_new(rsa_parameters, modulus, mod_len, pub_exp, pub_len);
2166 + * Similar to RSA_pub_key_new, rewritten to make this program depend only on bi module
2168 +void CH_pub_key_new(RSA_parameters **rsa, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len)
2170 + RSA_parameters *rsa_parameters;
2172 + BI_CTX *bi_ctx = bi_initialize();
2173 + *rsa = (RSA_parameters *)calloc(1, sizeof(RSA_parameters));
2174 + rsa_parameters = *rsa;
2175 + rsa_parameters->bi_ctx = bi_ctx;
2176 + rsa_parameters->num_octets = (mod_len & 0xFFF0);
2177 + rsa_parameters->m = bi_import(bi_ctx, modulus, mod_len);
2178 + bi_set_mod(bi_ctx, rsa_parameters->m, BIGINT_M_OFFSET);
2179 + rsa_parameters->e = bi_import(bi_ctx, pub_exp, pub_len);
2180 + bi_permanent(rsa_parameters->e);
2183 +static unsigned char *load_file_in_buffer(char *path, int *size)
2185 + unsigned char *buffer;
2189 + if (stat(path, &st))
2191 + buffer = (unsigned char *)malloc(st.st_size);
2192 + if (buffer == NULL)
2194 + if ((fd = open(path, O_RDONLY)) == -1) {
2198 + if (read(fd, (void *)buffer,st.st_size) != (ssize_t)st.st_size) {
2203 + *size = (int)st.st_size;
2208 +static int save_file_from_buffer(char *path, unsigned char *buffer, int size)
2212 + if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) == -1)
2214 + if (write(fd, buffer, (size_t)size) != ((ssize_t)size)) {
2223 +void *FR_init(char *public_key_path)
2226 + RSA_parameters *rsa_parameters;
2229 + ending = public_key_path + strlen(public_key_path) - 3;
2230 + if (!strcmp(ending, "der"))
2231 + derkey = CH_load_der_key(public_key_path);
2232 + else if (!strcmp(ending, "pem"))
2233 + derkey = CH_load_pem_key(public_key_path);
2235 + fprintf(stderr, "Error: unknown key format\n");
2238 + if (derkey == NULL) {
2239 + fprintf(stderr, "Error: opening key file '%s'\n", public_key_path);
2242 + if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
2243 + fprintf(stderr, "Error: Extracting public key from file\n");
2246 + CH_free_der_key(derkey);
2247 + return (void *)rsa_parameters;
2251 +FONRSA_ERROR FR_end(void *handle)
2253 + RSA_parameters *rsa_parameters = (RSA_parameters *)handle;
2255 + free(rsa_parameters);
2259 +/* FR_decrypt_buffer */
2260 +FONRSA_ERROR FR_decrypt_buffer(void *handler, unsigned char *cryptext, int cryptext_size,
2261 + unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size)
2263 + RSA_parameters *rsaparms = (RSA_parameters *)handler;
2265 + if (cryptext_size != rsaparms->num_octets) {
2266 + return FONRSA_SIZE;
2268 + if (plaintext_buffer_size < cryptext_size) {
2269 + return FONRSA_SIZE;
2271 + if (CH_decrypt(rsaparms, (uint8_t *)cryptext, (uint8_t *)plaintext)) {
2272 + return FONRSA_DECRYPT;
2274 + *plaintext_size = cryptext_size;
2278 +FONRSA_ERROR FR_decrypt_buffer_v2(void *handler, unsigned char *cryptext, int cryptext_size,
2279 + unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size)
2281 + unsigned char* AuxBuffer;
2284 + AuxBuffer = (unsigned char*)malloc(cryptext_size);
2286 + RSA_parameters *rsaparms = (RSA_parameters *)handler;
2288 + if (cryptext_size != rsaparms->num_octets) {
2289 + return FONRSA_SIZE;
2291 + if (plaintext_buffer_size < cryptext_size) {
2292 + return FONRSA_SIZE;
2294 + if (CH_decrypt(rsaparms, (uint8_t *)cryptext, (uint8_t *)AuxBuffer)) {
2295 + return FONRSA_DECRYPT;
2297 + if ((AuxSize = ExtractPadding((uint8_t*)plaintext, (uint8_t*)AuxBuffer, cryptext_size)) < 0)
2299 + printf("Incorrect Padding decrypting buffer");
2300 + return FONRSA_DECRYPT;
2302 + *plaintext_size = AuxSize;
2308 + * Implementation of PKCS 1.5 padding, borrowed from
2309 + * Tom's code (public domain)
2312 +/* Standalone FR_verify_file */
2313 +FONRSA_ERROR FR_verify_file(void *handler, char *file_path, char *signature_file_path)
2318 + uint8_t *decrypted;
2319 + RSA_parameters *rsa_parameters = (RSA_parameters *)handler;
2320 + char *signature_buffer;
2321 + int signature_size;
2323 + /* Calculates the RIPEMD-160 hash of the file */
2324 + hashcode = RMDbinary (file_path);
2325 + /* Decrypts the signature file using the RSA public key */
2326 + signature_buffer = load_file_in_buffer(signature_file_path, &signature_size);
2327 + if (signature_buffer == NULL)
2328 + return FONRSA_OPENKEY;
2330 + if (rsa_parameters->num_octets != signature_size)
2331 + return FONRSA_SIZE;
2332 + decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
2333 + if (CH_decrypt(rsa_parameters, signature_buffer, decrypted)) {
2334 + fprintf(stderr, "Error: Decrypting signature\n");
2337 + memcpy(hash, decrypted + 492, 20);
2339 + free(signature_buffer);
2340 + for (j = 0; j < RMDsize/8; j++) {
2341 + if (hash[j] != hashcode[j])
2342 + return FONRSA_VERIFICATION_FAILURE;
2347 +/* FR_decrypt_file */
2348 +FONRSA_ERROR FR_decrypt_file(void *handle, char *crypted_file_path, char *plaintext_file_path)
2353 + char crypted[1024];
2356 + if ((filebuffer = load_file_in_buffer(crypted_file_path, &size)) == NULL) {
2357 + return FONRSA_LOADFILE;
2360 + ret = FR_decrypt_buffer(handle, filebuffer, size, crypted, 1024, &crypted_size);
2361 + if (ret != FONRSA_OK) {
2367 + if (save_file_from_buffer(plaintext_file_path, crypted, crypted_size)) {
2368 + printf("Error writing %lu bytes into %s", crypted_size, plaintext_file_path);
2369 + return FONRSA_SAVEFILE;
2374 +int ExtractPadding(uint8_t* OutputBuffer, uint8_t* InputBuffer, int LengthOfInputBuffer)
2378 + //First typical checks...
2379 + if (LengthOfInputBuffer < MINIMUM_PADING_BYTES_PKCS_1_5)
2381 + fprintf(stderr, "Error:ExtractPadding: Error, Length of input buffer is too short.\n");
2384 + else if((InputBuffer[0] != 0) || (InputBuffer[1] > 2)) //Necessary header of Padding...
2386 + fprintf(stderr, "Error:ExtractPadding: Error, Padding header is incorrect.\n");
2389 + for (i=2; i < LengthOfInputBuffer; i++) //Variable size of non-zero padding....
2391 + if (InputBuffer[i] == 0) break; //This is the end of Padding.
2393 + //We need to evaluate if there is an existing message...
2394 + if (i < LengthOfInputBuffer - 2)
2395 + {//Ok, Padding is extracted... copying the message and finishing...
2396 + memcpy(OutputBuffer, &(InputBuffer[i + 1]), LengthOfInputBuffer - (i + 1));
2397 + return LengthOfInputBuffer - (i + 1);
2399 + //If we have reached to this point, then an error has occurred...
2403 +#ifdef __MAINTEST__
2404 +int main(int argc, char **argv)
2406 + void *handle = NULL;
2408 + char *filebuffer = NULL;
2409 + char crypted[1024];
2410 + int size, crypted_size;
2413 + printf("Usage: %s <key_file> <crypted_file> <output_file>\n", argv[0]);
2417 + handle = FR_init(argv[1]);
2418 + if (handle == NULL) {
2419 + printf("Error loading keys\n");
2422 + ret = FR_decrypt_file(handle, argv[2], argv[3]);
2423 + if (ret != FONRSA_OK) {
2424 + printf("FR_decrypt_file returns %d\n", ret);
2434 +++ b/net/rsa/fonrsa.h
2437 + * FONSM RSA handling library, used by fonsmcd and foncheckrsa
2439 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2441 + * This library is free software; you can redistribute it and/or modify
2442 + * it under the terms of the GNU Lesser General Public License as published by
2443 + * the Free Software Foundation; either version 2 of the License, or
2444 + * (at your option) any later version.
2446 + * This library is distributed in the hope that it will be useful,
2447 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2448 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2449 + * GNU Lesser General Public License for more details.
2451 + * You should have received a copy of the GNU Lesser General Public License
2452 + * along with this library; if not, write to the Free Software
2453 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2455 + * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
2457 + * $Id: fonrsa.h 404 2007-09-17 10:41:31Z jesus.pico $
2462 +#define MINIMUM_PADING_BYTES_PKCS_1_5 3
2466 + FONRSA_VERIFICATION_FAILURE = 1,
2467 + FONRSA_OPENKEY = 2,
2469 + FONRSA_LOADFILE = 4,
2471 + FONRSA_DECRYPT = 6,
2472 + FONRSA_SAVEFILE = 7,
2477 +void *FR_init(char *public_key_path);
2478 +FONRSA_ERROR FR_end(void *handle);
2479 +FONRSA_ERROR FR_decrypt_buffer(void *handler, unsigned char *cryptext, int cryptext_size,
2480 + unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size);
2481 +FONRSA_ERROR FR_decrypt_buffer_v2(void *handler, unsigned char *cryptext, int cryptext_size,
2482 + unsigned char *plaintext, int plaintext_buffer_size, int *plaintext_size);
2483 +FONRSA_ERROR FR_verify_file(void *handler, char *file_path, char *signature_file_path);
2484 +FONRSA_ERROR FR_decrypt_file(void *handler, char *crypted_file_path, char *plaintext_file_path);
2493 + * Fonsm log module. Used inside the fonsm backend module and on the client.
2495 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2497 + * Created: 20070202 Pablo Martin Medrano <pablo@fon.com>
2499 + * $Id: log.c 392 2007-06-25 16:24:51Z pablo.martin $
2502 +#include <string.h>
2503 +#include <stdlib.h>
2504 +#include <stdarg.h>
2505 +#include <unistd.h>
2507 +#include <syslog.h>
2511 +#define MAX_SESSION_PREFIX 256
2515 + LG_LEVEL watermark;
2517 + LG_log_function_pointer function;
2520 +static ST_fslog fslog;
2521 +static void LG_log_string(LG_LEVEL level, const char *message);
2524 + \brief Starts the log subsystem, redirecting glog() to stderr/syslog depending
2526 + \retval FSLOG_ERROR : FSLOG_OK if everything goes well
2527 + \param lg : handle that will be returned
2528 + \param ident : program identifier, any string
2529 + \param low_watermark : if the log level is less than this value, it will not be logged
2530 + \param mode : FSLOG_MODE_SYSLOG (log to syslog) or FSLOG_MODE_STDERR (log to stderr)
2532 +FSLOG_ERROR LG_start(const char *domain, LG_LEVEL watermark, int mode,
2533 + LG_log_function_pointer log_function, int facility)
2536 + strncpy(fslog.domain, domain, MAX_LG_DOMAIN);
2537 + fslog.domain[MAX_LG_DOMAIN - 1] = '\0';
2538 + fslog.watermark = watermark;
2539 + fslog.mode = mode;
2540 + fslog.function = log_function?log_function:LG_log_string;
2541 + if (fslog.mode & LG_SYSLOG)
2542 + openlog(domain, LOG_NDELAY, facility);
2550 + \brief Set the low watermark
2551 + \retval FSLOG_ERROR : FSLOG_OK
2552 + \param lg : log handle
2553 + \param low_watermark : new watermark
2555 +FSLOG_ERROR LG_set_loglevel(LG_LEVEL watermark)
2557 + fslog.watermark = watermark;
2562 + \brief Ends the log subsystem, unregisteing glog handle
2563 + \retval FSLOG_ERROR : FSLOG_OK if everything goes well
2564 + \param handle : log handle to free
2566 +FSLOG_ERROR LG_end(void)
2569 + if (fslog.mode & LG_SYSLOG)
2576 +void LG_log(LG_LEVEL loglevel, const char *message, ...)
2580 + char buffer[4096];
2583 + va_start(ap, message);
2584 + n = vsnprintf(buffer, MAX_LOG_STRING, message, ap);
2586 + if (n > -1 && n < MAX_LOG_STRING)
2587 + fslog.function(loglevel, buffer);
2589 + fon_critical("%s: Message too big to be logged", __FUNCTION__);
2595 +/* Default log function (when mode is LG_SYSLOG or LG_STDERR) */
2596 +static void LG_log_string(LG_LEVEL level, const char *message)
2602 + } fonlog_to_syslog[] = {
2603 + [LG_DEBUG] = {LOG_ERR, "DEBUG"},
2604 + [LG_MESSAGE] = {LOG_ERR, "MESSAGE"},
2605 + [LG_WARNING] = {LOG_ERR, "WARNING"},
2606 + [LG_CRITICAL] = {LOG_ERR, "CRITICAL"},
2607 + [LG_ERROR] = {LOG_ERR, "ERROR"}
2610 + if (level < fslog.watermark)
2612 + if (fslog.mode & LG_SYSLOG) {
2613 + if (level == LG_MESSAGE) {
2614 + syslog(LOG_INFO, "%s", message);
2616 + syslog(fonlog_to_syslog[level].syslog_level, "%s: %s", fonlog_to_syslog[level].log_string, message);
2619 + if (fslog.mode & LG_STDERR) {
2620 + fprintf(stderr, "%s[%d]: %8.8s: %s\n", fslog.domain,
2621 + getpid(), fonlog_to_syslog[level].log_string,
2634 + * Fonsm log module. Used inside the fonsm backend module and on the client.
2636 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
2638 + * Created: 20070202 Pablo Martin Medrano <pablo@fon.com>
2640 + * $Id: log.h 379 2007-05-28 09:17:48Z pablo.martin $
2649 +#include <stdarg.h>
2653 + FSLOG_UNKNOWN = -1
2657 +typedef void * LG_HANDLE;
2668 +#define LG_SYSLOG 0x01
2669 +#define LG_STDERR 0x02
2670 +#define LG_CUSTOM 0x04
2672 +#define MAX_LG_DOMAIN 256
2673 +#define MAX_LOG_STRING 4096
2677 +#define fon_debug(...) LG_log (LG_DEBUG, __VA_ARGS__)
2679 +#define fon_debug(...) { printf("DEBUG: "); printf(__VA_ARGS__); printf("\n"); }
2682 +/* fon_debug evaluates to nothing when NDEBUG is defined */
2683 +#define fon_debug(...)
2686 +#define fon_message(...) LG_log (LG_MESSAGE, __VA_ARGS__)
2687 +#define fon_warning(...) LG_log (LG_WARNING, __VA_ARGS__)
2688 +#define fon_critical(...) LG_log (LG_CRITICAL, __VA_ARGS__)
2689 +#define fon_error(...) LG_log (LG_ERROR, __VA_ARGS__)
2691 +#define fon_message(...) { printf("MESSAGE: "); printf(__VA_ARGS__); printf("\n"); }
2692 +#define fon_warning(...) { printf("WARNING: "); printf(__VA_ARGS__); printf("\n"); }
2693 +#define fon_critical(...) { printf("CRITICAL: "); printf(__VA_ARGS__); printf("\n"); }
2694 +#define fon_error(...) { printf("ERROR: "); printf(__VA_ARGS__); printf("\n"); }
2697 +typedef void (*LG_log_function_pointer)(LG_LEVEL level, const char *message);
2699 +FSLOG_ERROR LG_start(const char *domain, LG_LEVEL watermark, int mode, LG_log_function_pointer log_function, int facility);
2700 +FSLOG_ERROR LG_set_loglevel(LG_LEVEL watermark);
2701 +FSLOG_ERROR LG_end(void);
2702 +void LG_log(LG_LEVEL loglevel, const char *message, ...);
2711 +++ b/net/rsa/public_key.h
2713 +unsigned char public_key[] = {
2714 + 0x2D,0x2D,0x2D,0x2D,0x2D,0x42,0x45,0x47,0x49,0x4E,0x20,0x50,0x55,0x42,0x4C,0x49,
2715 + 0x43,0x20,0x4B,0x45,0x59,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,0x4D,0x49,0x49,0x43,0x49,
2716 + 0x6A,0x41,0x4E,0x42,0x67,0x6B,0x71,0x68,0x6B,0x69,0x47,0x39,0x77,0x30,0x42,0x41,
2717 + 0x51,0x45,0x46,0x41,0x41,0x4F,0x43,0x41,0x67,0x38,0x41,0x4D,0x49,0x49,0x43,0x43,
2718 + 0x67,0x4B,0x43,0x41,0x67,0x45,0x41,0x34,0x4C,0x42,0x76,0x59,0x43,0x4B,0x38,0x38,
2719 + 0x6D,0x75,0x57,0x61,0x73,0x31,0x4F,0x53,0x73,0x71,0x30,0x0A,0x38,0x39,0x38,0x79,
2720 + 0x76,0x54,0x4B,0x71,0x41,0x6E,0x4F,0x37,0x78,0x2F,0x44,0x53,0x57,0x72,0x46,0x53,
2721 + 0x30,0x42,0x72,0x47,0x53,0x51,0x31,0x52,0x69,0x44,0x39,0x55,0x62,0x78,0x77,0x6F,
2722 + 0x64,0x76,0x36,0x65,0x51,0x4B,0x55,0x30,0x67,0x36,0x52,0x6B,0x2F,0x39,0x54,0x70,
2723 + 0x4C,0x6E,0x4F,0x2F,0x76,0x51,0x4B,0x70,0x69,0x41,0x30,0x30,0x0A,0x2B,0x32,0x59,
2724 + 0x30,0x74,0x6B,0x4C,0x39,0x73,0x6A,0x37,0x64,0x33,0x57,0x4B,0x47,0x39,0x62,0x6A,
2725 + 0x64,0x51,0x58,0x2F,0x43,0x49,0x35,0x57,0x46,0x42,0x42,0x64,0x77,0x57,0x73,0x74,
2726 + 0x4D,0x43,0x38,0x77,0x74,0x4C,0x6A,0x6A,0x45,0x59,0x79,0x43,0x58,0x46,0x32,0x31,
2727 + 0x30,0x39,0x7A,0x31,0x47,0x54,0x4C,0x73,0x53,0x44,0x34,0x57,0x4F,0x0A,0x45,0x50,
2728 + 0x6D,0x45,0x37,0x34,0x63,0x6E,0x6F,0x35,0x78,0x53,0x43,0x71,0x71,0x33,0x74,0x54,
2729 + 0x49,0x6D,0x38,0x50,0x78,0x49,0x77,0x54,0x46,0x6D,0x46,0x6F,0x6D,0x6A,0x76,0x31,
2730 + 0x4F,0x56,0x50,0x32,0x73,0x42,0x49,0x70,0x35,0x4E,0x2B,0x59,0x6F,0x56,0x61,0x53,
2731 + 0x58,0x6A,0x47,0x66,0x4E,0x63,0x54,0x36,0x4E,0x6B,0x39,0x76,0x6B,0x56,0x0A,0x57,
2732 + 0x69,0x67,0x39,0x30,0x71,0x50,0x4E,0x4C,0x58,0x6E,0x39,0x39,0x50,0x78,0x48,0x61,
2733 + 0x49,0x31,0x36,0x52,0x7A,0x78,0x48,0x4C,0x39,0x54,0x42,0x2B,0x50,0x43,0x33,0x68,
2734 + 0x33,0x61,0x58,0x33,0x71,0x57,0x30,0x4B,0x4C,0x4A,0x41,0x66,0x6F,0x35,0x70,0x48,
2735 + 0x6C,0x39,0x79,0x75,0x55,0x70,0x37,0x66,0x46,0x65,0x6A,0x4A,0x2B,0x41,0x58,0x0A,
2736 + 0x51,0x4F,0x4A,0x62,0x53,0x45,0x67,0x56,0x74,0x76,0x72,0x68,0x44,0x39,0x73,0x55,
2737 + 0x6D,0x4B,0x30,0x74,0x36,0x63,0x51,0x44,0x65,0x32,0x32,0x4E,0x4E,0x6E,0x77,0x37,
2738 + 0x43,0x4F,0x4F,0x61,0x59,0x49,0x57,0x55,0x55,0x6A,0x79,0x6A,0x68,0x35,0x50,0x4B,
2739 + 0x64,0x64,0x45,0x4B,0x5A,0x38,0x68,0x62,0x62,0x47,0x65,0x61,0x5A,0x4A,0x6F,0x76,
2740 + 0x0A,0x63,0x6F,0x51,0x64,0x55,0x56,0x51,0x6D,0x71,0x44,0x53,0x2B,0x6B,0x63,0x2F,
2741 + 0x41,0x51,0x6C,0x65,0x55,0x36,0x68,0x51,0x6A,0x63,0x55,0x4C,0x57,0x44,0x6B,0x4E,
2742 + 0x2F,0x6F,0x4F,0x6C,0x33,0x43,0x53,0x65,0x70,0x67,0x54,0x37,0x6B,0x67,0x73,0x52,
2743 + 0x63,0x63,0x47,0x74,0x66,0x4B,0x65,0x37,0x77,0x4D,0x70,0x35,0x66,0x59,0x4A,0x2B,
2744 + 0x41,0x0A,0x43,0x46,0x44,0x41,0x6F,0x4C,0x6E,0x58,0x4E,0x6A,0x4E,0x56,0x6C,0x65,
2745 + 0x73,0x43,0x6B,0x78,0x74,0x6A,0x62,0x4C,0x62,0x49,0x72,0x66,0x32,0x6E,0x43,0x62,
2746 + 0x32,0x61,0x4D,0x65,0x64,0x31,0x5A,0x48,0x4E,0x4A,0x51,0x75,0x6F,0x4E,0x58,0x67,
2747 + 0x72,0x43,0x41,0x44,0x31,0x71,0x2B,0x58,0x6E,0x66,0x77,0x63,0x69,0x6D,0x57,0x50,
2748 + 0x64,0x51,0x0A,0x44,0x59,0x6A,0x6D,0x65,0x44,0x70,0x35,0x77,0x36,0x41,0x4A,0x33,
2749 + 0x2F,0x35,0x59,0x39,0x55,0x74,0x78,0x47,0x34,0x72,0x51,0x72,0x61,0x68,0x78,0x53,
2750 + 0x42,0x77,0x43,0x4B,0x57,0x39,0x4B,0x79,0x53,0x31,0x71,0x53,0x76,0x73,0x37,0x7A,
2751 + 0x59,0x2F,0x52,0x59,0x37,0x4A,0x66,0x36,0x63,0x56,0x6B,0x54,0x43,0x78,0x69,0x33,
2752 + 0x7A,0x32,0x53,0x0A,0x50,0x46,0x33,0x51,0x64,0x6B,0x30,0x50,0x44,0x2F,0x73,0x2B,
2753 + 0x6B,0x77,0x39,0x71,0x4F,0x4E,0x79,0x69,0x33,0x67,0x6E,0x61,0x42,0x46,0x6E,0x54,
2754 + 0x77,0x48,0x7A,0x59,0x69,0x77,0x34,0x2F,0x77,0x6A,0x46,0x33,0x64,0x47,0x68,0x47,
2755 + 0x4E,0x6B,0x78,0x36,0x70,0x63,0x4E,0x4F,0x52,0x55,0x46,0x4E,0x65,0x4F,0x7A,0x59,
2756 + 0x76,0x39,0x6F,0x6A,0x0A,0x51,0x59,0x70,0x73,0x55,0x31,0x33,0x6A,0x6D,0x30,0x33,
2757 + 0x42,0x6F,0x45,0x2B,0x42,0x31,0x64,0x38,0x50,0x47,0x75,0x57,0x2B,0x49,0x7A,0x2F,
2758 + 0x41,0x4F,0x44,0x7A,0x6B,0x6F,0x56,0x6B,0x39,0x2B,0x57,0x79,0x49,0x33,0x37,0x50,
2759 + 0x30,0x53,0x7A,0x47,0x4B,0x72,0x2B,0x53,0x33,0x72,0x72,0x74,0x61,0x50,0x6C,0x41,
2760 + 0x70,0x71,0x4B,0x48,0x55,0x0A,0x6E,0x64,0x35,0x6C,0x30,0x63,0x76,0x75,0x59,0x66,
2761 + 0x31,0x4C,0x37,0x45,0x52,0x75,0x49,0x58,0x64,0x47,0x4C,0x6A,0x30,0x43,0x41,0x77,
2762 + 0x45,0x41,0x41,0x51,0x3D,0x3D,0x0A,0x2D,0x2D,0x2D,0x2D,0x2D,0x45,0x4E,0x44,0x20,
2763 + 0x50,0x55,0x42,0x4C,0x49,0x43,0x20,0x4B,0x45,0x59,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,
2766 +++ b/net/rsa/rmd160.c
2768 +/********************************************************************\
2772 + * CONTENTS: A sample C-implementation of the RIPEMD-160
2774 + * TARGET: any computer with an ANSI C compiler
2776 + * AUTHOR: Antoon Bosselaers, ESAT-COSIC
2777 + * DATE: 1 March 1996
2780 + * Copyright (c) Katholieke Universiteit Leuven
2781 + * 1996, All Rights Reserved
2783 + * Conditions for use of the RIPEMD-160 Software
2785 + * The RIPEMD-160 software is freely available for use under the terms and
2786 + * conditions described hereunder, which shall be deemed to be accepted by
2787 + * any user of the software and applicable on any use of the software:
2789 + * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
2790 + * all purposes be considered the owner of the RIPEMD-160 software and of
2791 + * all copyright, trade secret, patent or other intellectual property
2793 + * 2. The RIPEMD-160 software is provided on an "as is" basis without
2794 + * warranty of any sort, express or implied. K.U.Leuven makes no
2795 + * representation that the use of the software will not infringe any
2796 + * patent or proprietary right of third parties. User will indemnify
2797 + * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
2798 + * which may arise as a result of its use of the software. In no
2799 + * circumstances K.U.Leuven R&D will be held liable for any deficiency,
2800 + * fault or other mishappening with regard to the use or performance of
2802 + * 3. User agrees to give due credit to K.U.Leuven in scientific publications
2803 + * or communications in relation with the use of the RIPEMD-160 software
2804 + * as follows: RIPEMD-160 software written by Antoon Bosselaers,
2805 + * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
2807 +\********************************************************************/
2810 +#include <common.h>
2811 +#include "rmd160.h"
2813 +/********************************************************************/
2815 +void MDinit(dword *MDbuf)
2817 + MDbuf[0] = 0x67452301UL;
2818 + MDbuf[1] = 0xefcdab89UL;
2819 + MDbuf[2] = 0x98badcfeUL;
2820 + MDbuf[3] = 0x10325476UL;
2821 + MDbuf[4] = 0xc3d2e1f0UL;
2826 +/********************************************************************/
2828 +void compress(dword *MDbuf, dword *X)
2830 + dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
2831 + dd = MDbuf[3], ee = MDbuf[4];
2832 + dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
2833 + ddd = MDbuf[3], eee = MDbuf[4];
2836 + FF(aa, bb, cc, dd, ee, X[ 0], 11);
2837 + FF(ee, aa, bb, cc, dd, X[ 1], 14);
2838 + FF(dd, ee, aa, bb, cc, X[ 2], 15);
2839 + FF(cc, dd, ee, aa, bb, X[ 3], 12);
2840 + FF(bb, cc, dd, ee, aa, X[ 4], 5);
2841 + FF(aa, bb, cc, dd, ee, X[ 5], 8);
2842 + FF(ee, aa, bb, cc, dd, X[ 6], 7);
2843 + FF(dd, ee, aa, bb, cc, X[ 7], 9);
2844 + FF(cc, dd, ee, aa, bb, X[ 8], 11);
2845 + FF(bb, cc, dd, ee, aa, X[ 9], 13);
2846 + FF(aa, bb, cc, dd, ee, X[10], 14);
2847 + FF(ee, aa, bb, cc, dd, X[11], 15);
2848 + FF(dd, ee, aa, bb, cc, X[12], 6);
2849 + FF(cc, dd, ee, aa, bb, X[13], 7);
2850 + FF(bb, cc, dd, ee, aa, X[14], 9);
2851 + FF(aa, bb, cc, dd, ee, X[15], 8);
2854 + GG(ee, aa, bb, cc, dd, X[ 7], 7);
2855 + GG(dd, ee, aa, bb, cc, X[ 4], 6);
2856 + GG(cc, dd, ee, aa, bb, X[13], 8);
2857 + GG(bb, cc, dd, ee, aa, X[ 1], 13);
2858 + GG(aa, bb, cc, dd, ee, X[10], 11);
2859 + GG(ee, aa, bb, cc, dd, X[ 6], 9);
2860 + GG(dd, ee, aa, bb, cc, X[15], 7);
2861 + GG(cc, dd, ee, aa, bb, X[ 3], 15);
2862 + GG(bb, cc, dd, ee, aa, X[12], 7);
2863 + GG(aa, bb, cc, dd, ee, X[ 0], 12);
2864 + GG(ee, aa, bb, cc, dd, X[ 9], 15);
2865 + GG(dd, ee, aa, bb, cc, X[ 5], 9);
2866 + GG(cc, dd, ee, aa, bb, X[ 2], 11);
2867 + GG(bb, cc, dd, ee, aa, X[14], 7);
2868 + GG(aa, bb, cc, dd, ee, X[11], 13);
2869 + GG(ee, aa, bb, cc, dd, X[ 8], 12);
2872 + HH(dd, ee, aa, bb, cc, X[ 3], 11);
2873 + HH(cc, dd, ee, aa, bb, X[10], 13);
2874 + HH(bb, cc, dd, ee, aa, X[14], 6);
2875 + HH(aa, bb, cc, dd, ee, X[ 4], 7);
2876 + HH(ee, aa, bb, cc, dd, X[ 9], 14);
2877 + HH(dd, ee, aa, bb, cc, X[15], 9);
2878 + HH(cc, dd, ee, aa, bb, X[ 8], 13);
2879 + HH(bb, cc, dd, ee, aa, X[ 1], 15);
2880 + HH(aa, bb, cc, dd, ee, X[ 2], 14);
2881 + HH(ee, aa, bb, cc, dd, X[ 7], 8);
2882 + HH(dd, ee, aa, bb, cc, X[ 0], 13);
2883 + HH(cc, dd, ee, aa, bb, X[ 6], 6);
2884 + HH(bb, cc, dd, ee, aa, X[13], 5);
2885 + HH(aa, bb, cc, dd, ee, X[11], 12);
2886 + HH(ee, aa, bb, cc, dd, X[ 5], 7);
2887 + HH(dd, ee, aa, bb, cc, X[12], 5);
2890 + II(cc, dd, ee, aa, bb, X[ 1], 11);
2891 + II(bb, cc, dd, ee, aa, X[ 9], 12);
2892 + II(aa, bb, cc, dd, ee, X[11], 14);
2893 + II(ee, aa, bb, cc, dd, X[10], 15);
2894 + II(dd, ee, aa, bb, cc, X[ 0], 14);
2895 + II(cc, dd, ee, aa, bb, X[ 8], 15);
2896 + II(bb, cc, dd, ee, aa, X[12], 9);
2897 + II(aa, bb, cc, dd, ee, X[ 4], 8);
2898 + II(ee, aa, bb, cc, dd, X[13], 9);
2899 + II(dd, ee, aa, bb, cc, X[ 3], 14);
2900 + II(cc, dd, ee, aa, bb, X[ 7], 5);
2901 + II(bb, cc, dd, ee, aa, X[15], 6);
2902 + II(aa, bb, cc, dd, ee, X[14], 8);
2903 + II(ee, aa, bb, cc, dd, X[ 5], 6);
2904 + II(dd, ee, aa, bb, cc, X[ 6], 5);
2905 + II(cc, dd, ee, aa, bb, X[ 2], 12);
2908 + JJ(bb, cc, dd, ee, aa, X[ 4], 9);
2909 + JJ(aa, bb, cc, dd, ee, X[ 0], 15);
2910 + JJ(ee, aa, bb, cc, dd, X[ 5], 5);
2911 + JJ(dd, ee, aa, bb, cc, X[ 9], 11);
2912 + JJ(cc, dd, ee, aa, bb, X[ 7], 6);
2913 + JJ(bb, cc, dd, ee, aa, X[12], 8);
2914 + JJ(aa, bb, cc, dd, ee, X[ 2], 13);
2915 + JJ(ee, aa, bb, cc, dd, X[10], 12);
2916 + JJ(dd, ee, aa, bb, cc, X[14], 5);
2917 + JJ(cc, dd, ee, aa, bb, X[ 1], 12);
2918 + JJ(bb, cc, dd, ee, aa, X[ 3], 13);
2919 + JJ(aa, bb, cc, dd, ee, X[ 8], 14);
2920 + JJ(ee, aa, bb, cc, dd, X[11], 11);
2921 + JJ(dd, ee, aa, bb, cc, X[ 6], 8);
2922 + JJ(cc, dd, ee, aa, bb, X[15], 5);
2923 + JJ(bb, cc, dd, ee, aa, X[13], 6);
2925 + /* parallel round 1 */
2926 + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
2927 + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
2928 + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
2929 + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
2930 + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
2931 + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
2932 + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
2933 + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
2934 + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
2935 + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
2936 + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
2937 + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
2938 + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
2939 + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
2940 + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
2941 + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
2943 + /* parallel round 2 */
2944 + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
2945 + III(ddd, eee, aaa, bbb, ccc, X[11], 13);
2946 + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
2947 + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
2948 + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
2949 + III(eee, aaa, bbb, ccc, ddd, X[13], 8);
2950 + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
2951 + III(ccc, ddd, eee, aaa, bbb, X[10], 11);
2952 + III(bbb, ccc, ddd, eee, aaa, X[14], 7);
2953 + III(aaa, bbb, ccc, ddd, eee, X[15], 7);
2954 + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
2955 + III(ddd, eee, aaa, bbb, ccc, X[12], 7);
2956 + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
2957 + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
2958 + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
2959 + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
2961 + /* parallel round 3 */
2962 + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
2963 + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
2964 + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
2965 + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
2966 + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
2967 + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
2968 + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
2969 + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
2970 + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
2971 + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
2972 + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
2973 + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
2974 + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
2975 + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
2976 + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
2977 + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
2979 + /* parallel round 4 */
2980 + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
2981 + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
2982 + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
2983 + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
2984 + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
2985 + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
2986 + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
2987 + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
2988 + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
2989 + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
2990 + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
2991 + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
2992 + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
2993 + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
2994 + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
2995 + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
2997 + /* parallel round 5 */
2998 + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
2999 + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
3000 + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
3001 + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
3002 + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
3003 + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
3004 + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
3005 + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
3006 + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
3007 + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
3008 + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
3009 + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
3010 + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
3011 + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
3012 + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
3013 + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
3015 + /* combine results */
3016 + ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
3017 + MDbuf[1] = MDbuf[2] + dd + eee;
3018 + MDbuf[2] = MDbuf[3] + ee + aaa;
3019 + MDbuf[3] = MDbuf[4] + aa + bbb;
3020 + MDbuf[4] = MDbuf[0] + bb + ccc;
3026 +/********************************************************************/
3028 +void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen)
3030 + unsigned int i; /* counter */
3031 + dword X[16]; /* message words */
3033 + memset(X, 0, 16*sizeof(dword));
3035 + /* put bytes from strptr into X */
3036 + for (i=0; i<(lswlen&63); i++) {
3037 + /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
3038 + X[i>>2] ^= (dword) *strptr++ << (8 * (i&3));
3041 + /* append the bit m_n == 1 */
3042 + X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7);
3044 + if ((lswlen & 63) > 55) {
3045 + /* length goes to next block */
3046 + compress(MDbuf, X);
3047 + memset(X, 0, 16*sizeof(dword));
3050 + /* append length in bits*/
3051 + X[14] = lswlen << 3;
3052 + X[15] = (lswlen >> 29) | (mswlen << 3);
3053 + compress(MDbuf, X);
3058 +/************************ end of file rmd160.c **********************/
3061 +++ b/net/rsa/rmd160.h
3063 +/********************************************************************\
3067 + * CONTENTS: Header file for a sample C-implementation of the
3068 + * RIPEMD-160 hash-function.
3069 + * TARGET: any computer with an ANSI C compiler
3071 + * AUTHOR: Antoon Bosselaers, ESAT-COSIC
3072 + * DATE: 1 March 1996
3075 + * Copyright (c) Katholieke Universiteit Leuven
3076 + * 1996, All Rights Reserved
3078 + * Conditions for use of the RIPEMD-160 Software
3080 + * The RIPEMD-160 software is freely available for use under the terms and
3081 + * conditions described hereunder, which shall be deemed to be accepted by
3082 + * any user of the software and applicable on any use of the software:
3084 + * 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
3085 + * all purposes be considered the owner of the RIPEMD-160 software and of
3086 + * all copyright, trade secret, patent or other intellectual property
3088 + * 2. The RIPEMD-160 software is provided on an "as is" basis without
3089 + * warranty of any sort, express or implied. K.U.Leuven makes no
3090 + * representation that the use of the software will not infringe any
3091 + * patent or proprietary right of third parties. User will indemnify
3092 + * K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
3093 + * which may arise as a result of its use of the software. In no
3094 + * circumstances K.U.Leuven R&D will be held liable for any deficiency,
3095 + * fault or other mishappening with regard to the use or performance of
3097 + * 3. User agrees to give due credit to K.U.Leuven in scientific publications
3098 + * or communications in relation with the use of the RIPEMD-160 software
3099 + * as follows: RIPEMD-160 software written by Antoon Bosselaers,
3100 + * available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
3102 +\********************************************************************/
3104 +#ifndef RMD160H /* make sure this file is read only once */
3107 +/********************************************************************/
3109 +/* typedef 8 and 32 bit types, resp. */
3110 +/* adapt these, if necessary,
3111 + for your operating system and compiler */
3112 +typedef unsigned char byte;
3113 +typedef unsigned long dword;
3116 +/********************************************************************/
3118 +/* macro definitions */
3120 +/* collect four bytes into one word: */
3121 +#define BYTES_TO_DWORD(strptr) \
3122 + (((dword) *((strptr)+3) << 24) | \
3123 + ((dword) *((strptr)+2) << 16) | \
3124 + ((dword) *((strptr)+1) << 8) | \
3125 + ((dword) *(strptr)))
3127 +/* ROL(x, n) cyclically rotates x over n bits to the left */
3128 +/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
3129 +#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
3131 +/* the five basic functions F(), G() and H() */
3132 +#define F(x, y, z) ((x) ^ (y) ^ (z))
3133 +#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
3134 +#define H(x, y, z) (((x) | ~(y)) ^ (z))
3135 +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
3136 +#define J(x, y, z) ((x) ^ ((y) | ~(z)))
3138 +/* the ten basic operations FF() through III() */
3139 +#define FF(a, b, c, d, e, x, s) {\
3140 + (a) += F((b), (c), (d)) + (x);\
3141 + (a) = ROL((a), (s)) + (e);\
3142 + (c) = ROL((c), 10);\
3144 +#define GG(a, b, c, d, e, x, s) {\
3145 + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
3146 + (a) = ROL((a), (s)) + (e);\
3147 + (c) = ROL((c), 10);\
3149 +#define HH(a, b, c, d, e, x, s) {\
3150 + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
3151 + (a) = ROL((a), (s)) + (e);\
3152 + (c) = ROL((c), 10);\
3154 +#define II(a, b, c, d, e, x, s) {\
3155 + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
3156 + (a) = ROL((a), (s)) + (e);\
3157 + (c) = ROL((c), 10);\
3159 +#define JJ(a, b, c, d, e, x, s) {\
3160 + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
3161 + (a) = ROL((a), (s)) + (e);\
3162 + (c) = ROL((c), 10);\
3164 +#define FFF(a, b, c, d, e, x, s) {\
3165 + (a) += F((b), (c), (d)) + (x);\
3166 + (a) = ROL((a), (s)) + (e);\
3167 + (c) = ROL((c), 10);\
3169 +#define GGG(a, b, c, d, e, x, s) {\
3170 + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
3171 + (a) = ROL((a), (s)) + (e);\
3172 + (c) = ROL((c), 10);\
3174 +#define HHH(a, b, c, d, e, x, s) {\
3175 + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
3176 + (a) = ROL((a), (s)) + (e);\
3177 + (c) = ROL((c), 10);\
3179 +#define III(a, b, c, d, e, x, s) {\
3180 + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
3181 + (a) = ROL((a), (s)) + (e);\
3182 + (c) = ROL((c), 10);\
3184 +#define JJJ(a, b, c, d, e, x, s) {\
3185 + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
3186 + (a) = ROL((a), (s)) + (e);\
3187 + (c) = ROL((c), 10);\
3190 +/********************************************************************/
3192 +/* function prototypes */
3194 +void MDinit(dword *MDbuf);
3196 + * initializes MDbuffer to "magic constants"
3199 +void compress(dword *MDbuf, dword *X);
3201 + * the compression function.
3202 + * transforms MDbuf using message bytes X[0] through X[15]
3205 +void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen);
3207 + * puts bytes from strptr into X and pad out; appends length
3208 + * and finally, compresses the last block(s)
3209 + * note: length in bits == 8 * (lswlen + 2^32 mswlen).
3210 + * note: there are (lswlen mod 64) bytes left in strptr.
3213 +#endif /* RMD160H */
3215 +/*********************** end of file rmd160.h ***********************/
3221 + * FONSM RSA handling library
3223 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
3225 + * This library is free software; you can redistribute it and/or modify
3226 + * it under the terms of the GNU Lesser General Public License as published by
3227 + * the Free Software Foundation; either version 2 of the License, or
3228 + * (at your option) any later version.
3230 + * This library is distributed in the hope that it will be useful,
3231 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3232 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3233 + * GNU Lesser General Public License for more details.
3235 + * You should have received a copy of the GNU Lesser General Public License
3236 + * along with this library; if not, write to the Free Software
3237 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3239 + * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
3243 + * $Id: fonrsa.c 405 2007-09-19 15:26:17Z jesus.pico $
3245 +#include <malloc.h>
3246 +#include <common.h>
3248 +#include "rmd160.h"
3249 +#include "bigint.h"
3250 +#include "base64.h"
3252 +#include "public_key.h"
3254 +#define RMDsize 160 /* A RIPEMD-160 hash has 160 bits */
3262 + bigint *m; /* modulus */
3263 + bigint *e; /* public exponent */
3265 + BI_CTX *bi_ctx; /* big integer handle */
3270 + RSA_parameters *rsaparms;
3273 +static void CH_free_der_key(DER_key *key)
3275 + free(key->buffer);
3279 +int CH_decrypt(RSA_parameters *rsa, uint8_t *buffer_in, uint8_t *buffer_out)
3282 + bigint *decrypted_bi;
3285 + byte_size = rsa->num_octets;
3286 + dat_bi = bi_import(rsa->bi_ctx, buffer_in, byte_size);
3287 + rsa->bi_ctx->mod_offset = BIGINT_M_OFFSET;
3289 + decrypted_bi = bi_mod_power(rsa->bi_ctx, dat_bi, rsa->e);
3290 + bi_export(rsa->bi_ctx, decrypted_bi, buffer_out, byte_size);
3294 +byte *RMDbinary(char *buffer, int len)
3296 + byte data[1024]; /* contains current mess. block */
3297 + dword nbytes; /* length of this block */
3298 + dword MDbuf[RMDsize / 32]; /* contains (A, B, C, D(, E)) */
3299 + static byte hashcode[RMDsize / 8]; /* for final hash-value */
3300 + dword X[16]; /* current 16-word chunk */
3301 + unsigned int i, j; /* counters */
3302 + dword length[2]; /* length in bytes of message */
3303 + dword offset; /* # of unprocessed bytes at */
3304 + /* call of MDfinish */
3306 + char *tmp = buffer;
3311 + memcpy(data, tmp, 1024);
3321 + /* process all complete blocks */
3322 + for (i = 0; i < (nbytes >> 6); i++) {
3323 + for (j = 0; j < 16; j++)
3324 + X[j] = BYTES_TO_DWORD(data + 64 * i + 4 * j);
3325 + compress(MDbuf, X);
3327 + /* update length[] */
3328 + if (length[0] + nbytes < length[0])
3329 + length[1]++; /* overflow to msb of length */
3330 + length[0] += nbytes;
3333 + offset = length[0] & 0x3C0; /* extract bytes 6 to 10 inclusive */
3334 + MDfinish(MDbuf, data + offset, length[0], length[1]);
3336 + for (i = 0; i < RMDsize / 8; i += 4) {
3337 + hashcode[i] = MDbuf[i >> 2];
3338 + hashcode[i + 1] = (MDbuf[i >> 2] >> 8);
3339 + hashcode[i + 2] = (MDbuf[i >> 2] >> 16);
3340 + hashcode[i + 3] = (MDbuf[i >> 2] >> 24);
3343 + return (byte *) hashcode;
3346 +static DER_key *CH_load_pem_key(void)
3355 + if ((ret = (DER_key *)malloc(sizeof(DER_key))) == NULL)
3357 + buffer = public_key;
3358 + p = (char *)buffer;
3359 + while ((*p != '\n') && (*p != '\0'))
3367 + while((p - b64) <= filesize) {
3368 + if ((*p == '-')) {
3370 + } else if ((*p != '\n') && (*p != ' ') && (*p != '\t')) {
3377 + size = B64_decode(b64, key, strlen(b64), 1024);
3384 + ret->buffer = (char *)malloc(size);
3386 + memcpy((void *)ret->buffer, (void *)key, size);
3391 + * Similar to RSA_pub_key_new, rewritten to make this program depend only on bi module
3393 +void CH_pub_key_new(RSA_parameters **rsa, const uint8_t *modulus, int mod_len, const uint8_t *pub_exp, int pub_len)
3395 + RSA_parameters *rsa_parameters;
3397 + BI_CTX *bi_ctx = bi_initialize();
3398 + *rsa = (RSA_parameters *)calloc(1, sizeof(RSA_parameters));
3399 + rsa_parameters = *rsa;
3400 + rsa_parameters->bi_ctx = bi_ctx;
3401 + rsa_parameters->num_octets = (mod_len & 0xFFF0);
3402 + rsa_parameters->m = bi_import(bi_ctx, modulus, mod_len);
3403 + bi_set_mod(bi_ctx, rsa_parameters->m, BIGINT_M_OFFSET);
3404 + rsa_parameters->e = bi_import(bi_ctx, pub_exp, pub_len);
3405 + bi_permanent(rsa_parameters->e);
3409 + * Get the public key specifics from an ASN.1 encoded file
3410 + * A function lacking in the exported axTLS API
3412 + * This is a really weird hack that only works with RSA public key
3415 +static int asn1_get_public_key(const uint8_t *buf, int len, RSA_parameters **rsa_parameters)
3417 + uint8_t *modulus, *pub_exp;
3418 + int mod_len, pub_len;
3421 + mod_len = len - 37;
3422 + if (buf[0] != 0x30) {
3426 + pub_exp = (uint8_t *)malloc(3);
3427 + modulus = (uint8_t *)malloc(mod_len);
3428 + memcpy(modulus, buf + 32 , mod_len);
3429 + memcpy(pub_exp, buf + 34 + mod_len, 3);
3430 + if (mod_len <= 0 || pub_len <= 0 )
3432 + CH_pub_key_new(rsa_parameters, modulus, mod_len, pub_exp, pub_len);
3441 +void *FR_init(void)
3444 + RSA_parameters *rsa_parameters;
3446 + derkey = CH_load_pem_key();
3447 + if ((asn1_get_public_key(derkey->buffer, derkey->size, &rsa_parameters)) != 0) {
3448 + fprintf(stderr, "Error: Extracting public key from file\n");
3451 + CH_free_der_key(derkey);
3452 + return (void *)rsa_parameters;
3455 +FONRSA_ERROR FR_end(void *handle)
3457 + RSA_parameters *rsa_parameters = (RSA_parameters *)handle;
3459 + free(rsa_parameters);
3465 + * Implementation of PKCS 1.5 padding, borrowed from
3466 + * Tom's code (public domain)
3469 +/* Standalone FR_verify_file */
3470 +FONRSA_ERROR FR_verify_file(void *handler, char *file_data, int file_len,
3471 + char *signature_buffer, int signature_size)
3476 + uint8_t *decrypted;
3477 + RSA_parameters *rsa_parameters = (RSA_parameters *)handler;
3479 + /* Calculates the RIPEMD-160 hash of the file */
3480 + hashcode = RMDbinary (file_data, file_len);
3482 + if (rsa_parameters->num_octets != signature_size)
3483 + return FONRSA_SIZE;
3484 + decrypted = (uint8_t *)malloc(rsa_parameters->num_octets);
3485 + if (CH_decrypt(rsa_parameters, signature_buffer, decrypted)) {
3486 + printf("Error: Decrypting signature\n");
3487 + return FONRSA_VERIFICATION_FAILURE;
3489 + memcpy(hash, decrypted + 492, 20);
3490 + //free(decrypted);
3491 + //free(signature_buffer);
3492 + for (j = 0; j < RMDsize/8; j++) {
3493 + if (hash[j] != hashcode[j])
3494 + return FONRSA_VERIFICATION_FAILURE;
3499 +int rsa_check_signature(char *signature, int signature_len, char *buffer, int buffer_len)
3501 + FONRSA_ERROR fonrsa_error;
3503 + handle = FR_init();
3504 + if (handle == NULL) {
3505 + printf("Error loading keys\n");
3508 + fonrsa_error = FR_verify_file(handle, buffer, buffer_len, signature, signature_len);
3510 + switch (fonrsa_error) {
3512 + printf("Verified OK\n");
3514 + case FONRSA_VERIFICATION_FAILURE:
3515 + printf("Verification failure\n");
3518 + printf("Verification error\n");
3527 + * FONSM RSA handling library, used by fonsmcd and foncheckrsa
3529 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
3531 + * This library is free software; you can redistribute it and/or modify
3532 + * it under the terms of the GNU Lesser General Public License as published by
3533 + * the Free Software Foundation; either version 2 of the License, or
3534 + * (at your option) any later version.
3536 + * This library is distributed in the hope that it will be useful,
3537 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3538 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3539 + * GNU Lesser General Public License for more details.
3541 + * You should have received a copy of the GNU Lesser General Public License
3542 + * along with this library; if not, write to the Free Software
3543 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3545 + * Created: 20070306 Pablo Martin Medrano <pablo@fon.com>
3547 + * $Id: fonrsa.h 404 2007-09-17 10:41:31Z jesus.pico $
3552 +#define MINIMUM_PADING_BYTES_PKCS_1_5 3
3556 + FONRSA_VERIFICATION_FAILURE = 1,
3557 + FONRSA_OPENKEY = 2,
3559 + FONRSA_LOADFILE = 4,
3561 + FONRSA_DECRYPT = 6,
3562 + FONRSA_SAVEFILE = 7,
3567 +int rsa_check_signature(char *signature, int signature_len, char *buffer, int buffer_len);
3573 +++ b/net/rsa/sign.h
3576 + * Signature interface
3578 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
3580 + * Created: 20070417 Pablo MartÃn Medrano <pablo@fon.com>
3582 + * $Id: sign.h 389 2007-06-11 08:29:56Z pablo.martin $
3590 +void SG_init(void);
3591 +void *SG_start(char *private_key_path, char *public_key_path);
3592 +void SG_stop(void *handle);
3593 +int SG_crypt(void *data, unsigned char *text, int size_text, unsigned char *crypted_text,
3594 + unsigned int crypted_text_buffer_size, int *crypted_size);
3595 +int SG_crypt_v2(void *data, unsigned char *text, int size_text, unsigned char *crypted_text,
3596 + unsigned int crypted_text_buffer_size, int *crypted_size);
3600 +#endif /* #ifdef __SIGN_H__ */
3603 +++ b/net/rsa/sign_openssl.c
3606 + * Signature using OpenSSL
3608 + * This file is part of FONUCS. Copyright (C) 2007 FON Wireless Ltd.
3610 + * Created: 20070417 Pablo MartÃn Medrano <pablo@fon.com>
3612 + * $Id: sign_openssl.c 346 2007-05-10 19:51:38Z pablo.martin $
3616 + * How the RSA public and private key was generated
3617 + * To check .FON files
3618 + * openssl genrsa -out private_fon_rsa_key.pem 4096
3619 + * openssl rsa -in private_fon_rsa_key.pem -pubout -out public_fon_rsa_key.pem
3621 + * How the Status Manager public and private key was generated
3622 + * openssl genrsa -out private_sm_rsa_key.pem 2048
3623 + * openssl rsa -in private_sm_rsa_key.pem -pubout -out public_sm_rsa_key.pem
3625 + * How to sign using the RSA private key (This is what fonsign does)
3626 + * openssl dgst -rmd160 -sign private_fon_rsa_key.pem FILE > SIGNATURE
3627 + * How to verify using the RSA public key (This is what fonverify + foncheckrsa does)
3628 + * openssl dgst -rmd160 -verify public_fon_rsa_key.pem -signature SIGNATURE FILE
3629 + * Convert to DER file (to use it in La Fonera)
3630 + * openssl rsa -inform PEM -outform DER -pubin -in public_fon_rsa_key.pem -pubout -out public_fon_rsa_key.der
3632 +#include <openssl/rsa.h>
3633 +#include <openssl/ssl.h>
3634 +#include <openssl/bn.h>
3635 +#include <openssl/pem.h>
3636 +#include <openssl/evp.h>
3637 +#include <sys/stat.h>
3639 +#ifndef __MAINTEST__
3642 +#define fon_warning printf
3643 +#define fon_debug printf
3644 +#define fon_critical printf
3654 + int public_rsa_size;
3655 + EVP_PKEY *public_pkey;
3656 + int public_pkey_size;
3664 +static EVP_PKEY *SG_load_key(char *key_path, KEY_TYPE type);
3665 +static unsigned char *load_file_in_buffer(char *path, int *size);
3666 +static int save_file_from_buffer(char *path, char *buffer, int size);
3670 + SSL_load_error_strings();
3671 + SSL_library_init();
3672 + OpenSSL_add_all_algorithms();
3673 + OpenSSL_add_all_ciphers();
3674 + OpenSSL_add_all_digests();
3677 +static unsigned char *load_file_in_buffer(char *path, int *size)
3683 + if (stat(path, &st))
3685 + buffer = (char *)malloc(st.st_size);
3686 + if (buffer == NULL)
3688 + if ((fd = open(path, O_RDONLY)) == -1) {
3692 + if (read(fd,buffer,st.st_size) != (ssize_t)st.st_size) {
3697 + *size = (int)st.st_size;
3702 +static int save_file_from_buffer(char *path, char *buffer, int size)
3706 + if ((fd = open(path, O_WRONLY | O_CREAT, 0644)) == -1)
3708 + if (write(fd, buffer, (size_t)size) != ((ssize_t)size)) {
3716 +static EVP_PKEY *SG_load_key(char *key_path, KEY_TYPE type)
3721 + if ((key = BIO_new(BIO_s_file())) == NULL) {
3722 + //ERR_print_errors(err);
3723 + fon_warning("%s: Error calling BIO_new()\n", __FUNCTION__);
3726 + if (BIO_read_filename(key, key_path) <= 0) {
3727 + fon_warning("%s: Error opening %s\n", __FUNCTION__, key_path);
3728 + // ERR_print_errors(err);
3731 + if (type == KEY_PUBLIC) {
3732 + pkey = PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
3733 + } else if (type == KEY_PRIVATE) {
3734 + pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL);
3739 + if (pkey == NULL) {
3740 + fon_warning("%s: Error reading %s\n", __FUNCTION__, key_path);
3748 +void *SG_start(char *private_key_path, char *public_key_path)
3752 + if ((sign = (Sign *)malloc(sizeof(Sign))) == NULL)
3754 + memset(sign, 0, sizeof(Sign));
3755 + if (private_key_path != NULL) {
3756 + if ((sign->pkey = SG_load_key(private_key_path, KEY_PRIVATE)) == NULL) {
3757 + fon_warning("%s: Error loading %s", __FUNCTION__, private_key_path);
3761 + if (public_key_path != NULL) {
3762 + if ((sign->public_pkey = SG_load_key(public_key_path, KEY_PUBLIC)) == NULL) {
3763 + fon_warning("%s: Error loading %s", __FUNCTION__, public_key_path);
3767 + if (sign->pkey != NULL) {
3768 + sign->pkey_size = EVP_PKEY_size(sign->pkey);
3769 + if ((sign->rsa = EVP_PKEY_get1_RSA(sign->pkey)) == NULL) {
3770 + EVP_PKEY_free(sign->pkey);
3774 + if (sign->public_pkey != NULL) {
3775 + sign->public_pkey_size = EVP_PKEY_size(sign->public_pkey);
3776 + if ((sign->public_rsa = EVP_PKEY_get1_RSA(sign->public_pkey)) == NULL) {
3777 + EVP_PKEY_free(sign->pkey);
3781 + if (((sign->rsa == NULL) && (private_key_path != NULL)) ||
3782 + ((sign->public_rsa == NULL) && (public_key_path != NULL))) {
3783 + fon_warning("%s: Error calling EVP_PKEY_get1_RSA()", __FUNCTION__);
3786 + if (sign->rsa != NULL) {
3787 + sign->rsa_size = RSA_size(sign->rsa);
3788 + if (RSA_check_key(sign->rsa) != 1) {
3789 + fon_warning("%s: RSA key failure", __FUNCTION__);
3794 + return (void *)sign;
3797 +void SG_stop(void *handle)
3799 + Sign *sign = (Sign *)handle;
3801 + EVP_PKEY_free(sign->pkey);
3802 + EVP_PKEY_free(sign->public_pkey);
3803 + if (sign->rsa != NULL)
3804 + RSA_free(sign->rsa);
3805 + if (sign->public_rsa != NULL)
3806 + RSA_free(sign->public_rsa);
3810 +int SG_verify(void *data, unsigned char *text, unsigned int size_text,
3811 + unsigned char *signature, unsigned int size_signature)
3817 + Sign *sign = (Sign *)data;
3819 + md = (EVP_MD *)EVP_ripemd160();
3820 + if(!EVP_VerifyInit(&mdctx, md))
3822 + if (!EVP_VerifyUpdate(&mdctx, (const void *)text, (unsigned int)size_text)) {
3825 + ret = EVP_VerifyFinal(&mdctx, (const char *)signature, size_signature, sign->public_pkey);
3826 + EVP_PKEY_free(pkey);
3827 + EVP_MD_CTX_cleanup(&mdctx);
3831 +int SG_sign(void *data, void *text, unsigned int size_text, void *signature_buffer,
3832 + unsigned int size_signature_buffer, unsigned int *size_signature)
3834 + unsigned char *digest[EVP_MAX_MD_SIZE];
3838 + Sign *sign = (Sign *)data;
3840 + if (size_signature_buffer < sign->pkey_size)
3843 + md = (EVP_MD *)EVP_ripemd160();
3844 + EVP_SignInit(&mdctx, md);
3845 + if (!EVP_SignUpdate(&mdctx, (const void *)text, (unsigned int)size_text)) {
3848 + if (!EVP_SignFinal(&mdctx, (unsigned char *)signature_buffer, (unsigned int *)size_signature, sign->pkey)) {
3851 + EVP_MD_CTX_cleanup(&mdctx);
3857 + * It's not advised to crypt using RAW ... unless you have crypted the buffer using AES before.
3859 +int SG_crypt(void *data, unsigned char *text, int size_text,
3860 + unsigned char *crypted_text, unsigned int crypted_text_buffer_size,
3861 + int *crypted_size)
3866 + Sign *sign = (Sign *)data;
3868 + if (crypted_text_buffer_size < sign->pkey_size) {
3869 + fon_critical("%s: size_signature_buffer [%u] < %u", __FUNCTION__, size_text, sign->pkey_size);
3872 + if (size_text != sign->pkey_size) {
3873 + fon_critical("%s: size_text [%u] != %u", __FUNCTION__, size_text, sign->pkey_size);
3876 + /* The buffer is pre-padded with random data ... */
3877 + fon_debug("%s: About to call RSA_private_encrypt(%d, %x, %x, %x, %d)",
3878 + __FUNCTION__, size_text, crypted_text, sign->rsa, RSA_NO_PADDING);
3879 + retsize = RSA_private_encrypt(size_text, text, crypted_text, sign->rsa, RSA_NO_PADDING);
3880 + if (retsize == -1) {
3881 + fon_critical("%s: Error calling RSA_private_encrypt(%d, %x, %x, %x, %d)",
3882 + __FUNCTION__, size_text, crypted_text, sign->rsa, RSA_NO_PADDING);
3885 + *crypted_size = retsize;
3890 +int SG_decrypt(void *data, unsigned char *cryptext, int cryptext_size, unsigned char *plaintext,
3891 + int plaintext_buffer_size, int *plaintext_size)
3896 + Sign *sign = (Sign *)data;
3898 + if (plaintext_buffer_size < sign->public_pkey_size) {
3899 + fon_critical("%s: plaintext_buffer_size [%u] < %u", __FUNCTION__, plaintext_buffer_size, sign->public_pkey_size);
3902 + if (cryptext_size != sign->public_pkey_size) {
3903 + fon_critical("%s: cryptext_size [%u] != %u", __FUNCTION__, cryptext_size, sign->public_pkey_size);
3906 + retsize = RSA_public_decrypt(cryptext_size, cryptext, plaintext, sign->public_rsa, RSA_NO_PADDING);
3907 + if (retsize == -1)
3909 + *plaintext_size = retsize;
3913 +#ifdef __MAINTEST__
3914 +int main(int argc, char **argv)
3916 + size_t argv0_size;
3919 + argv0_size = strlen(argv[0]);
3920 + if (argv0_size < 7) {
3921 + fprintf(stderr, "%s?", argv[0]);
3924 + token = argv[0] + argv0_size - 7;
3927 + if (!strcmp(token, "fonsign")) {
3928 + return main_fonsign(argc, argv);
3929 + } else if (!strcmp(token, "foncryp")) {
3930 + return main_foncryp(argc, argv);
3932 + fprintf(stderr, "%s?", argv[0]);
3936 +int main_foncryp(int argc, char **argv)
3938 + void *handle = NULL;
3940 + char *filebuffer = NULL;
3941 + char crypted[1024];
3942 + int size, crypted_size, ret;
3945 + printf("Usage: %s encrypt|decrypt <key_file> <file> <crypted_file>\n", argv[0]);
3948 + if (!strcmp(argv[1], "encrypt")) {
3949 + printf("Encryption mode\n");
3952 + printf("Decryption mode\n");
3954 + handle = SG_start(argv[2], NULL);
3956 + handle = SG_start(NULL, argv[2]);
3957 + if (handle == NULL) {
3958 + printf("Error loading keys\n");
3962 + filebuffer = load_file_in_buffer(argv[3], &size);
3963 + if (filebuffer == NULL) {
3964 + printf("Error reading %s\n", argv[3]);
3969 + ret = SG_crypt(handle, filebuffer, size, crypted, 1024, &crypted_size);
3971 + ret = SG_decrypt(handle, filebuffer, size, crypted, 1024, &crypted_size);
3974 + printf("Error crypting %d bytes\n", size);
3978 + printf("Crypted size %d\n", crypted_size);
3979 + if (save_file_from_buffer(argv[4], crypted, crypted_size)) {
3980 + printf("Error saving file\n");
3989 +int main_fonsign(int argc, char **argv)
3991 + void *handle = NULL;
3992 + char signature_buffer[4096];
3994 + unsigned int signature_size;
3996 + char *filebuffer = NULL;
4001 + fprintf(stderr, "usage: %s <private_key_file> <public_key_file> <file_to_sign> <signature_file>\n", argv[0]);
4004 + handle = SG_start(argv[1], argv[2]);
4005 + if (handle == NULL) {
4006 + fprintf(stderr, "Error calling SG_start(%s)\n", argv[1]);
4009 + filebuffer = load_file_in_buffer(argv[3], &size);
4010 + if (filebuffer == NULL) {
4011 + fprintf(stderr, "Error reading %s\n", argv[3]);
4014 + if (SG_sign(handle, filebuffer, size, signature_buffer, 4096, &signature_size)) {
4015 + fprintf(stderr, "Error calling SG_sign()\n");
4018 + ret = SG_verify(handle, filebuffer, size, signature_buffer, signature_size);
4020 + fprintf(stderr, "signature failure\n");
4021 + else if (ret == 1) {
4022 + fprintf(stderr, "signature ok\n");
4025 + fprintf(stderr, "signature error\n");
4028 + if (save_file_from_buffer(argv[4], signature_buffer, signature_size)) {
4029 + fprintf(stderr, "Error writing to %s\n", argv[4]);
4034 + if (filebuffer != NULL)
4036 + if (handle != NULL)
4043 +++ b/net/uip-0.9/Makefile
4045 +# Copyright (c) 2001, Adam Dunkels.
4046 +# All rights reserved.
4048 +# Redistribution and use in source and binary forms, with or without
4049 +# modification, are permitted provided that the following conditions
4051 +# 1. Redistributions of source code must retain the above copyright
4052 +# notice, this list of conditions and the following disclaimer.
4053 +# 2. Redistributions in binary form must reproduce the above copyright
4054 +# notice, this list of conditions and the following disclaimer in the
4055 +# documentation and/or other materials provided with the distribution.
4056 +# 3. All advertising materials mentioning features or use of this software
4057 +# must display the following acknowledgement:
4058 +# This product includes software developed by Adam Dunkels.
4059 +# 4. The name of the author may not be used to endorse or promote
4060 +# products derived from this software without specific prior
4061 +# written permission.
4063 +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4064 +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4065 +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4066 +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4067 +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4068 +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4069 +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4070 +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4071 +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4072 +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4073 +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4075 +# This file is part of the uIP TCP/IP stack.
4077 +# $Id: Makefile,v 1.8.2.2 2003/10/04 22:54:17 adam Exp $
4081 +CFLAGS=-Wall -fpack-struct -DDUMP=0
4085 +uip: uip.o uip_arch.o tapdev.o httpd.o main.o fs.o uip_arp.o
4086 + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
4089 + $(CC) $(CFLAGS) -c $^ -o $@
4092 + rm -f *.o *~ *core uip
4100 +++ b/net/uip-0.9/fs.c
4103 + * \addtogroup httpd
4109 + * HTTP server read-only file system code.
4110 + * \author Adam Dunkels <adam@dunkels.com>
4112 + * A simple read-only filesystem.
4116 + * Copyright (c) 2001, Swedish Institute of Computer Science.
4117 + * All rights reserved.
4119 + * Redistribution and use in source and binary forms, with or without
4120 + * modification, are permitted provided that the following conditions
4122 + * 1. Redistributions of source code must retain the above copyright
4123 + * notice, this list of conditions and the following disclaimer.
4124 + * 2. Redistributions in binary form must reproduce the above copyright
4125 + * notice, this list of conditions and the following disclaimer in the
4126 + * documentation and/or other materials provided with the distribution.
4127 + * 3. Neither the name of the Institute nor the names of its contributors
4128 + * may be used to endorse or promote products derived from this software
4129 + * without specific prior written permission.
4131 + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
4132 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4133 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4134 + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
4135 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4136 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4137 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4138 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4139 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4140 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4143 + * This file is part of the lwIP TCP/IP stack.
4145 + * Author: Adam Dunkels <adam@sics.se>
4147 + * $Id: fs.c,v 1.7.2.3 2003/10/07 13:22:27 adam Exp $
4153 +#include "fsdata.h"
4155 +#include "fsdata.c"
4157 +#ifdef FS_STATISTICS
4158 +#if FS_STATISTICS == 1
4159 +static u16_t count[FS_NUMFILES];
4160 +#endif /* FS_STATISTICS */
4161 +#endif /* FS_STATISTICS */
4163 +/*-----------------------------------------------------------------------------------*/
4165 +fs_strcmp(const char *str1, const char *str2)
4171 + if(str2[i] == 0 ||
4172 + str1[i] == '\r' ||
4173 + str1[i] == '\n') {
4177 + if(str1[i] != str2[i]) {
4185 +/*-----------------------------------------------------------------------------------*/
4187 +fs_open(const char *name, struct fs_file *file)
4189 +#ifdef FS_STATISTICS
4190 +#if FS_STATISTICS == 1
4192 +#endif /* FS_STATISTICS */
4193 +#endif /* FS_STATISTICS */
4194 + struct fsdata_file_noconst *f;
4196 + for(f = (struct fsdata_file_noconst *)FS_ROOT;
4198 + f = (struct fsdata_file_noconst *)f->next) {
4200 + if(fs_strcmp(name, f->name) == 0) {
4201 + file->data = f->data;
4202 + file->len = f->len;
4203 +#ifdef FS_STATISTICS
4204 +#if FS_STATISTICS == 1
4206 +#endif /* FS_STATISTICS */
4207 +#endif /* FS_STATISTICS */
4210 +#ifdef FS_STATISTICS
4211 +#if FS_STATISTICS == 1
4213 +#endif /* FS_STATISTICS */
4214 +#endif /* FS_STATISTICS */
4219 +/*-----------------------------------------------------------------------------------*/
4223 +#ifdef FS_STATISTICS
4224 +#if FS_STATISTICS == 1
4226 + for(i = 0; i < FS_NUMFILES; i++) {
4229 +#endif /* FS_STATISTICS */
4230 +#endif /* FS_STATISTICS */
4232 +/*-----------------------------------------------------------------------------------*/
4233 +#ifdef FS_STATISTICS
4234 +#if FS_STATISTICS == 1
4238 + struct fsdata_file_noconst *f;
4242 + for(f = (struct fsdata_file_noconst *)FS_ROOT;
4244 + f = (struct fsdata_file_noconst *)f->next) {
4246 + if(fs_strcmp(name, f->name) == 0) {
4253 +#endif /* FS_STATISTICS */
4254 +#endif /* FS_STATISTICS */
4255 +/*-----------------------------------------------------------------------------------*/
4257 +++ b/net/uip-0.9/fs.h
4260 + * \addtogroup httpd
4266 + * HTTP server read-only file system header file.
4267 + * \author Adam Dunkels <adam@dunkels.com>
4271 + * Copyright (c) 2001, Swedish Institute of Computer Science.
4272 + * All rights reserved.
4274 + * Redistribution and use in source and binary forms, with or without
4275 + * modification, are permitted provided that the following conditions
4277 + * 1. Redistributions of source code must retain the above copyright
4278 + * notice, this list of conditions and the following disclaimer.
4279 + * 2. Redistributions in binary form must reproduce the above copyright
4280 + * notice, this list of conditions and the following disclaimer in the
4281 + * documentation and/or other materials provided with the distribution.
4282 + * 3. Neither the name of the Institute nor the names of its contributors
4283 + * may be used to endorse or promote products derived from this software
4284 + * without specific prior written permission.
4286 + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
4287 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4288 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4289 + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
4290 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4291 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4292 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4293 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4294 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4295 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4298 + * This file is part of the lwIP TCP/IP stack.
4300 + * Author: Adam Dunkels <adam@sics.se>
4302 + * $Id: fs.h,v 1.6.2.3 2003/10/07 13:22:27 adam Exp $
4310 + * An open file in the read-only file system.
4313 + char *data; /**< The actual file data. */
4314 + int len; /**< The length of the file data. */
4318 + * Open a file in the read-only file system.
4320 + * \param name The name of the file.
4322 + * \param file The file pointer, which must be allocated by caller and
4323 + * will be filled in by the function.
4325 +int fs_open(const char *name, struct fs_file *file);
4327 +#ifdef FS_STATISTICS
4328 +#if FS_STATISTICS == 1
4329 +u16_t fs_count(char *name);
4330 +#endif /* FS_STATISTICS */
4331 +#endif /* FS_STATISTICS */
4334 + * Initialize the read-only file system.
4336 +void fs_init(void);
4338 +#endif /* __FS_H__ */
4340 +++ b/net/uip-0.9/fsdata.c
4342 +static const char data_flashing_html[] = {
4343 + /* /flashing.html */
4344 + 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4345 + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
4346 + 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
4347 + 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
4348 + 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4349 + 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
4350 + 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
4351 + 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
4352 + 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
4353 + 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
4354 + 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62,
4355 + 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d,
4356 + 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30,
4357 + 0x70, 0x74, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x20, 0x68,
4358 + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25,
4359 + 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23,
4360 + 0x66, 0x66, 0x66, 0x3b, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67,
4361 + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f,
4362 + 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62, 0x62, 0x30, 0x33, 0x34,
4363 + 0x3b, 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72,
4364 + 0x3e, 0x3c, 0x68, 0x31, 0x3e, 0x55, 0x70, 0x67, 0x72, 0x61,
4365 + 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
4366 + 0x6d, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x68, 0x31,
4367 + 0x3e, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
4368 + 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68,
4369 + 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
4371 +static const char data_fail_html[] = {
4373 + 0x2f, 0x66, 0x61, 0x69, 0x6c, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4374 + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
4375 + 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
4376 + 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
4377 + 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4378 + 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
4379 + 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
4380 + 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
4381 + 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
4382 + 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
4383 + 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
4384 + 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
4385 + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
4386 + 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
4387 + 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
4388 + 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
4389 + 0x3e, 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
4390 + 0x9, 0x9, 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73,
4391 + 0x68, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65,
4392 + 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9, 0x45,
4393 + 0x52, 0x52, 0x4f, 0x52, 0x20, 0x2d, 0x20, 0x74, 0x68, 0x65,
4394 + 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x79, 0x6f, 0x75,
4395 + 0x20, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20,
4396 + 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,
4397 + 0x70, 0x61, 0x73, 0x73, 0x20, 0x76, 0x65, 0x72, 0x69, 0x66,
4398 + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x50,
4399 + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x6b, 0x65,
4400 + 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75,
4401 + 0x73, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x66, 0x66, 0x69,
4402 + 0x63, 0x69, 0x61, 0x6c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74,
4403 + 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64,
4404 + 0x20, 0x62, 0x79, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4405 + 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2e,
4406 + 0x66, 0x6f, 0x6e, 0x6f, 0x73, 0x66, 0x65, 0x72, 0x61, 0x2e,
4407 + 0x6f, 0x72, 0x67, 0x2f, 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f,
4408 + 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
4411 +static const char data_404_html[] = {
4413 + 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4414 + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34,
4415 + 0x30, 0x34, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f,
4416 + 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53,
4417 + 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50,
4418 + 0x2f, 0x30, 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70,
4419 + 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73,
4420 + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f,
4421 + 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e,
4422 + 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a,
4423 + 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
4424 + 0xd, 0xa, 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e,
4425 + 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f,
4426 + 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65,
4427 + 0x22, 0x3e, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e,
4428 + 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20,
4429 + 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66,
4430 + 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c,
4431 + 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, 0x3c, 0x2f,
4432 + 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d,
4435 +static const char data_index_html[] = {
4437 + 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4438 + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
4439 + 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
4440 + 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
4441 + 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4442 + 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
4443 + 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
4444 + 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
4445 + 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
4446 + 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
4447 + 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
4448 + 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
4449 + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
4450 + 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
4451 + 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
4452 + 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
4453 + 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
4454 + 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
4455 + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
4456 + 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
4457 + 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
4458 + 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
4459 + 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
4460 + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
4461 + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
4462 + 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
4463 + 0x3c, 0x68, 0x31, 0x3e, 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65,
4464 + 0x72, 0x61, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66,
4465 + 0x65, 0x20, 0x55, 0x49, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa,
4466 + 0x9, 0x9, 0x3c, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65,
4467 + 0x74, 0x68, 0x6f, 0x64, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x74,
4468 + 0x22, 0x20, 0x65, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3d,
4469 + 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74,
4470 + 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61,
4471 + 0x22, 0x3e, 0xa, 0x9, 0x9, 0x9, 0x3c, 0x69, 0x6e, 0x70,
4472 + 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x69,
4473 + 0x6c, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x66, 0x69,
4474 + 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x3e, 0xa, 0x9, 0x9,
4475 + 0x9, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79,
4476 + 0x70, 0x65, 0x3d, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x3e,
4477 + 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x3e,
4478 + 0xa, 0x9, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa,
4479 + 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
4481 +static const char data_flash_html[] = {
4483 + 0x2f, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0,
4484 + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32,
4485 + 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72,
4486 + 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x30,
4487 + 0x2e, 0x39, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
4488 + 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63,
4489 + 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69,
4490 + 0x70, 0x2f, 0x29, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x74, 0x65,
4491 + 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
4492 + 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa,
4493 + 0xd, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x9,
4494 + 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x9, 0x9, 0x3c,
4495 + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x9, 0x9, 0x9,
4496 + 0x4c, 0x61, 0x46, 0x6f, 0x6e, 0x65, 0x72, 0x61, 0x20, 0x46,
4497 + 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x20, 0x55, 0x49,
4498 + 0xa, 0x9, 0x9, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65,
4499 + 0x3e, 0xa, 0x9, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e,
4500 + 0xa, 0x9, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x73, 0x74,
4501 + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69,
4502 + 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x74, 0x20, 0x61, 0x75, 0x74,
4503 + 0x6f, 0x3b, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a,
4504 + 0x31, 0x30, 0x30, 0x25, 0x3b, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
4505 + 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x62,
4506 + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d,
4507 + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x62,
4508 + 0x62, 0x30, 0x33, 0x34, 0x3b, 0x22, 0x3e, 0xa, 0x9, 0x9,
4509 + 0x3c, 0x68, 0x31, 0x3e, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x69,
4510 + 0x6e, 0x67, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x9, 0x9,
4511 + 0x54, 0x68, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
4512 + 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x72,
4513 + 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c,
4514 + 0x61, 0x73, 0x68, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68,
4515 + 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x70,
4516 + 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x2c, 0x20, 0x74, 0x68,
4517 + 0x65, 0x20, 0x6c, 0x65, 0x64, 0x73, 0x20, 0x77, 0x69, 0x6c,
4518 + 0x6c, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x74, 0x6f,
4519 + 0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0xa, 0xa, 0x9,
4520 + 0x9, 0x41, 0x66, 0x74, 0x65, 0x72, 0x20, 0x61, 0x20, 0x73,
4521 + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x6c,
4522 + 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68,
4523 + 0x65, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x77, 0x69, 0x6c, 0x6c,
4524 + 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0xa, 0x9, 0x3c,
4525 + 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68,
4526 + 0x74, 0x6d, 0x6c, 0x3e, 0xa, };
4528 +const struct fsdata_file file_flashing_html[] = {{NULL, data_flashing_html, data_flashing_html + 15, sizeof(data_flashing_html) - 15}};
4530 +const struct fsdata_file file_fail_html[] = {{file_flashing_html, data_fail_html, data_fail_html + 11, sizeof(data_fail_html) - 11}};
4532 +const struct fsdata_file file_404_html[] = {{file_fail_html, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}};
4534 +const struct fsdata_file file_index_html[] = {{file_404_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}};
4536 +const struct fsdata_file file_flash_html[] = {{file_index_html, data_flash_html, data_flash_html + 12, sizeof(data_flash_html) - 12}};
4538 +#define FS_ROOT file_flash_html
4540 +#define FS_NUMFILES 5
4541 \ No newline at end of file
4543 +++ b/net/uip-0.9/fsdata.h
4546 + * Copyright (c) 2001, Swedish Institute of Computer Science.
4547 + * All rights reserved.
4549 + * Redistribution and use in source and binary forms, with or without
4550 + * modification, are permitted provided that the following conditions
4552 + * 1. Redistributions of source code must retain the above copyright
4553 + * notice, this list of conditions and the following disclaimer.
4554 + * 2. Redistributions in binary form must reproduce the above copyright
4555 + * notice, this list of conditions and the following disclaimer in the
4556 + * documentation and/or other materials provided with the distribution.
4557 + * 3. Neither the name of the Institute nor the names of its contributors
4558 + * may be used to endorse or promote products derived from this software
4559 + * without specific prior written permission.
4561 + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
4562 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4563 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4564 + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
4565 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4566 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4567 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4568 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4569 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4570 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4573 + * This file is part of the lwIP TCP/IP stack.
4575 + * Author: Adam Dunkels <adam@sics.se>
4577 + * $Id: fsdata.h,v 1.4.2.1 2003/10/04 22:54:06 adam Exp $
4579 +#ifndef __FSDATA_H__
4580 +#define __FSDATA_H__
4582 +#include "uipopt.h"
4584 +struct fsdata_file {
4585 + const struct fsdata_file *next;
4589 +#ifdef FS_STATISTICS
4590 +#if FS_STATISTICS == 1
4592 +#endif /* FS_STATISTICS */
4593 +#endif /* FS_STATISTICS */
4596 +struct fsdata_file_noconst {
4597 + struct fsdata_file *next;
4601 +#ifdef FS_STATISTICS
4602 +#if FS_STATISTICS == 1
4604 +#endif /* FS_STATISTICS */
4605 +#endif /* FS_STATISTICS */
4608 +#endif /* __FSDATA_H__ */
4610 +++ b/net/uip-0.9/httpd.c
4615 +#include "fsdata.h"
4616 +#include <asm/addrspace.h>
4618 +#define HTTP_NONE 0
4619 +#define HTTP_FILE 1
4620 +#define HTTP_FIRMWARE 2
4622 +#define PRINT(x) printf("%s", x)
4623 +#define PRINTLN(x) printf("%s\n", x)
4625 +extern unsigned long do_http_tmp_address(void);
4627 +struct httpd_state *hs;
4629 +extern const struct fsdata_file file_index_html;
4630 +extern const struct fsdata_file file_404_html;
4631 +extern const struct fsdata_file file_flash_html;
4632 +extern int httpd_upload_complete;
4633 +extern unsigned char *httpd_upload_data;
4634 +unsigned char *upload_data;
4635 +extern ulong NetBootFileXferSize;
4636 +int upload_running = 0;
4645 +#define ISO_slash 0x2f
4649 +#define ISO_space 0x20
4650 +#define ISO_nl 0x0a
4651 +#define ISO_cr 0x0d
4654 +#define ISO_hash 0x23
4655 +#define ISO_period 0x2e
4657 +static char eol[3] = { 0x0d, 0x0a, 0x00 };
4658 +static char eol2[5] = { 0x0d, 0x0a, 0x0d, 0x0a, 0x00 };
4659 +static char boundary[128];
4660 +static int boundary_len = 0;
4662 +/* we use this so that we can do without the ctype library */
4663 +#define is_digit(c) ((c) >= '0' && (c) <= '9')
4664 +static int atoi(const char *s)
4668 + while (is_digit(*s))
4669 + i = i*10 + *(s++) - '0';
4677 + uip_listen(HTONS(80));
4681 +httpd_appcall(void)
4683 + struct fs_file fsfile;
4685 + switch(uip_conn->lport) {
4687 + hs = (struct httpd_state *)(uip_conn->appstate);
4688 + if(uip_connected())
4690 + hs->state = HTTP_NONE;
4693 + } else if(uip_poll())
4695 + if(hs->count++ >= 1000) {
4699 + } else if(uip_newdata() && hs->state == HTTP_NONE)
4701 + if(uip_appdata[0] == ISO_G &&
4702 + uip_appdata[1] == ISO_E &&
4703 + uip_appdata[2] == ISO_T &&
4704 + uip_appdata[3] == ISO_space)
4706 + hs->state = HTTP_FILE;
4708 + if(uip_appdata[0] == ISO_P &&
4709 + uip_appdata[1] == ISO_O &&
4710 + uip_appdata[2] == ISO_S &&
4711 + uip_appdata[3] == ISO_T &&
4712 + uip_appdata[4] == ISO_space)
4714 + hs->state = HTTP_FIRMWARE;
4716 + if(hs->state == HTTP_NONE)
4721 + if(hs->state == HTTP_FILE)
4723 + for(i = 4; i < 40; ++i)
4725 + if(uip_appdata[i] == ISO_space ||
4726 + uip_appdata[i] == ISO_cr ||
4727 + uip_appdata[i] == ISO_nl)
4729 + uip_appdata[i] = 0;
4734 + PRINT("request for file ");
4735 + PRINTLN(&uip_appdata[4]);
4736 + if(uip_appdata[4] == ISO_slash &&
4737 + uip_appdata[5] == 0)
4739 + fs_open(file_index_html.name, &fsfile);
4741 + if(!fs_open((const char *)&uip_appdata[4], &fsfile))
4743 + PRINTLN("couldn't open file");
4744 + fs_open(file_index_html.name, &fsfile);
4748 + hs->state = HTTP_FILE;
4749 + hs->dataptr = fsfile.data;
4750 + hs->count = fsfile.len;
4752 + if(hs->state == HTTP_FIRMWARE)
4754 + unsigned char *start = (unsigned char*)uip_appdata;
4755 + char *clen = strstr(start, "Content-Length:");
4757 + unsigned char *next, *end;
4758 + unsigned char *boundary_start;
4760 + uip_appdata[uip_len] = '\0';
4763 + clen += sizeof("Content-Length:");
4764 + next = strstr(clen, eol);
4769 + printf("expecting %d bytes\n", len);
4770 + upload_data = httpd_upload_data = (unsigned char *)do_http_tmp_address();
4771 + printf("received data will be stored at 0x%08X\n", upload_data);
4774 + printf("failed to allocate memory\n");
4783 + if(len < 4 * 1024)
4788 + boundary_start = strstr(next, "---");
4789 + if(!boundary_start)
4794 + end = strstr(boundary_start, eol);
4800 + boundary_len = end - boundary_start;
4801 + memcpy(boundary, boundary_start, boundary_len);
4802 + boundary[boundary_len] = 0;
4803 + next = strstr(boundary_start, "name=\"firmware\";");
4809 + next = strstr(next, eol2);
4812 + printf("could not find start of data\n");
4818 + hs->state = HTTP_FIRMWARE;
4819 + hs->upload = uip_len - (next - start);
4820 + hs->upload_total = len - (int)(next - boundary_start);
4821 + hs->upload_total -= (strlen(boundary) + 6);
4822 + //printf("storing %d bytes at %p\n", (int)hs->upload, upload_data);
4823 + for(i = 0; i < hs->upload; i++)
4824 + upload_data[i] = next[i];
4825 + upload_data += (int)hs->upload;
4826 + printf("%d / %d\n", (int)hs->upload, hs->upload_total);
4832 + if(hs->state == HTTP_FIRMWARE)
4838 + uip_appdata[uip_len] = '\0';
4839 + hs->upload += uip_len;
4840 + //printf("storing %d bytes at %p\n", uip_len, upload_data);
4841 + printf("%d / %d\n", (int)hs->upload, hs->upload_total);
4842 + for(i = 0; i < uip_len; i++)
4843 + upload_data[i] = uip_appdata[i];
4844 + upload_data += uip_len;
4846 + if(hs->upload >= hs->upload_total)
4848 + upload_running = 1;
4849 + NetBootFileXferSize = hs->upload_total;
4850 + fs_open(file_flash_html.name, &fsfile);
4852 + hs->state = HTTP_FILE;
4853 + hs->dataptr = fsfile.data;
4854 + hs->count = fsfile.len;
4858 + if(hs->state == HTTP_FILE)
4862 + if(hs->count >= uip_conn->len)
4864 + hs->count -= uip_conn->len;
4865 + hs->dataptr += uip_conn->len;
4869 + if(hs->count == 0)
4871 + if(upload_running)
4874 + httpd_upload_complete = 1;
4875 + // for(i = 0; i < hs->upload_total; i++)
4876 + // printf("%c", httpd_upload_data[i]);
4881 + uip_send(hs->dataptr, hs->count);
4891 +++ b/net/uip-0.9/httpd.h
4894 + * \addtogroup httpd
4900 + * HTTP server header file.
4901 + * \author Adam Dunkels <adam@dunkels.com>
4905 + * Copyright (c) 2001, Adam Dunkels.
4906 + * All rights reserved.
4908 + * Redistribution and use in source and binary forms, with or without
4909 + * modification, are permitted provided that the following conditions
4911 + * 1. Redistributions of source code must retain the above copyright
4912 + * notice, this list of conditions and the following disclaimer.
4913 + * 2. Redistributions in binary form must reproduce the above copyright
4914 + * notice, this list of conditions and the following disclaimer in the
4915 + * documentation and/or other materials provided with the distribution.
4916 + * 3. The name of the author may not be used to endorse or promote
4917 + * products derived from this software without specific prior
4918 + * written permission.
4920 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4921 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4922 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4923 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4924 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4925 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4926 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4927 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4928 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4929 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4930 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4932 + * This file is part of the uIP TCP/IP stack.
4934 + * $Id: httpd.h,v 1.4.2.3 2003/10/06 22:56:44 adam Exp $
4938 +#ifndef __HTTPD_H__
4939 +#define __HTTPD_H__
4941 +void httpd_init(void);
4942 +void httpd_appcall(void);
4944 +/* UIP_APPCALL: the name of the application function. This function
4945 + must return void and take no arguments (i.e., C type "void
4946 + appfunc(void)"). */
4947 +#ifndef UIP_APPCALL
4948 +#define UIP_APPCALL httpd_appcall
4951 +struct httpd_state {
4956 + unsigned int upload;
4957 + unsigned int upload_total;
4961 +/* UIP_APPSTATE_SIZE: The size of the application-specific state
4962 + stored in the uip_conn structure. */
4963 +#ifndef UIP_APPSTATE_SIZE
4964 +#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
4967 +#define FS_STATISTICS 1
4969 +extern struct httpd_state *hs;
4972 +/* we copy the data to RAM+10MB */
4973 +#define TMP_DATA 0x8A100000
4975 +#endif /* __HTTPD_H__ */
4977 +++ b/net/uip-0.9/main.c
4980 + * Copyright (c) 2001-2003, Adam Dunkels.
4981 + * All rights reserved.
4983 + * Redistribution and use in source and binary forms, with or without
4984 + * modification, are permitted provided that the following conditions
4986 + * 1. Redistributions of source code must retain the above copyright
4987 + * notice, this list of conditions and the following disclaimer.
4988 + * 2. Redistributions in binary form must reproduce the above copyright
4989 + * notice, this list of conditions and the following disclaimer in the
4990 + * documentation and/or other materials provided with the distribution.
4991 + * 3. The name of the author may not be used to endorse or promote
4992 + * products derived from this software without specific prior
4993 + * written permission.
4995 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4996 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4997 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4998 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4999 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5000 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5001 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5002 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5003 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5004 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5005 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5007 + * This file is part of the uIP TCP/IP stack.
5009 + * $Id: main.c,v 1.10.2.1 2003/10/04 22:54:17 adam Exp $
5015 +#include "uip_arp.h"
5016 +#include "tapdev.h"
5019 +#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
5022 +#define NULL (void *)0
5025 +/*-----------------------------------------------------------------------------------*/
5035 + uip_len = tapdev_read();
5036 + if(uip_len == 0) {
5037 + for(i = 0; i < UIP_CONNS; i++) {
5045 + if(++arptimer == 20) {
5050 + if(BUF->type == htons(UIP_ETHTYPE_IP)) {
5057 + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
5068 +++ b/net/uip-0.9/tapdev.c
5071 + * Copyright (c) 2001, Swedish Institute of Computer Science.
5072 + * All rights reserved.
5074 + * Redistribution and use in source and binary forms, with or without
5075 + * modification, are permitted provided that the following conditions
5078 + * 1. Redistributions of source code must retain the above copyright
5079 + * notice, this list of conditions and the following disclaimer.
5081 + * 2. Redistributions in binary form must reproduce the above copyright
5082 + * notice, this list of conditions and the following disclaimer in the
5083 + * documentation and/or other materials provided with the distribution.
5085 + * 3. Neither the name of the Institute nor the names of its contributors
5086 + * may be used to endorse or promote products derived from this software
5087 + * without specific prior written permission.
5089 + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
5090 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5091 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5092 + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
5093 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5094 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5095 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5096 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5097 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5098 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5101 + * Author: Adam Dunkels <adam@sics.se>
5103 + * $Id: tapdev.c,v 1.7.2.1 2003/10/07 13:23:19 adam Exp $
5108 +#include <stdlib.h>
5110 +#include <unistd.h>
5111 +#include <string.h>
5112 +#include <sys/ioctl.h>
5113 +#include <sys/socket.h>
5114 +#include <sys/types.h>
5115 +#include <sys/time.h>
5116 +#include <sys/uio.h>
5117 +#include <sys/socket.h>
5120 +#include <sys/ioctl.h>
5121 +#include <linux/if.h>
5122 +#include <linux/if_tun.h>
5123 +#define DEVTAP "/dev/net/tun"
5125 +#define DEVTAP "/dev/tap0"
5132 +static unsigned long lasttime;
5133 +static struct timezone tz;
5135 +/*-----------------------------------------------------------------------------------*/
5141 + fd = open(DEVTAP, O_RDWR);
5143 + perror("tapdev: tapdev_init: open");
5150 + memset(&ifr, 0, sizeof(ifr));
5151 + ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
5152 + if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
5159 + snprintf(buf, sizeof(buf), "ifconfig tap0 inet %d.%d.%d.%d",
5160 + UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3);
5166 +void dump_mem(int type, int len)
5170 + for(i = 0; i < len; i++)
5171 + printf("%c", uip_buf[i]);
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 + 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");
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 + 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");
5184 +/*-----------------------------------------------------------------------------------*/
5189 + struct timeval tv, now;
5192 + if(lasttime >= 500000) {
5198 + tv.tv_usec = 500000 - lasttime;
5202 + FD_SET(fd, &fdset);
5204 + gettimeofday(&now, &tz);
5205 + ret = select(fd + 1, &fdset, NULL, NULL, &tv);
5210 + ret = read(fd, uip_buf, UIP_BUFSIZE);
5212 + perror("tap_dev: tapdev_read: read");
5214 + gettimeofday(&tv, &tz);
5215 + lasttime += (tv.tv_sec - now.tv_sec) * 1000000 + (tv.tv_usec - now.tv_usec);
5219 +/*-----------------------------------------------------------------------------------*/
5224 + struct iovec iov[2];
5228 + char tmpbuf[UIP_BUFSIZE];
5231 + for(i = 0; i < 40 + UIP_LLH_LEN; i++) {
5232 + tmpbuf[i] = uip_buf[i];
5235 + for(; i < uip_len; i++) {
5236 + tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];
5239 + ret = write(fd, tmpbuf, uip_len);
5243 + if(uip_len < 40 + UIP_LLH_LEN) {
5244 + ret = write(fd, uip_buf, uip_len + UIP_LLH_LEN);
5246 + iov[0].iov_base = uip_buf;
5247 + iov[0].iov_len = 40 + UIP_LLH_LEN;
5248 + iov[1].iov_base = (char *)uip_appdata;
5249 + iov[1].iov_len = uip_len - (40 + UIP_LLH_LEN);
5251 + ret = writev(fd, iov, 2);
5257 + perror("tap_dev: tapdev_send: writev");
5261 +/*-----------------------------------------------------------------------------------*/
5263 +++ b/net/uip-0.9/tapdev.h
5266 + * Copyright (c) 2001, Adam Dunkels.
5267 + * All rights reserved.
5269 + * Redistribution and use in source and binary forms, with or without
5270 + * modification, are permitted provided that the following conditions
5272 + * 1. Redistributions of source code must retain the above copyright
5273 + * notice, this list of conditions and the following disclaimer.
5274 + * 2. Redistributions in binary form must reproduce the above copyright
5275 + * notice, this list of conditions and the following disclaimer in the
5276 + * documentation and/or other materials provided with the distribution.
5277 + * 3. The name of the author may not be used to endorse or promote
5278 + * products derived from this software without specific prior
5279 + * written permission.
5281 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5282 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5283 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5284 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5285 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5286 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5287 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5288 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5289 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5290 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5291 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5293 + * This file is part of the uIP TCP/IP stack.
5295 + * $Id: tapdev.h,v 1.1.2.1 2003/10/04 22:54:17 adam Exp $
5299 +#ifndef __TAPDEV_H__
5300 +#define __TAPDEV_H__
5302 +void tapdev_init(void);
5303 +unsigned int tapdev_read(void);
5304 +void tapdev_send(void);
5306 +#endif /* __TAPDEV_H__ */
5308 +++ b/net/uip-0.9/uip.c
5317 + * The uIP TCP/IP stack code.
5318 + * \author Adam Dunkels <adam@dunkels.com>
5322 + * Copyright (c) 2001-2003, Adam Dunkels.
5323 + * All rights reserved.
5325 + * Redistribution and use in source and binary forms, with or without
5326 + * modification, are permitted provided that the following conditions
5328 + * 1. Redistributions of source code must retain the above copyright
5329 + * notice, this list of conditions and the following disclaimer.
5330 + * 2. Redistributions in binary form must reproduce the above copyright
5331 + * notice, this list of conditions and the following disclaimer in the
5332 + * documentation and/or other materials provided with the distribution.
5333 + * 3. The name of the author may not be used to endorse or promote
5334 + * products derived from this software without specific prior
5335 + * written permission.
5337 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
5338 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5339 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5340 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
5341 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5342 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
5343 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5344 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5345 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
5346 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5347 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5349 + * This file is part of the uIP TCP/IP stack.
5351 + * $Id: uip.c,v 1.62.2.10 2003/10/07 13:23:01 adam Exp $
5356 +This is a small implementation of the IP and TCP protocols (as well as
5357 +some basic ICMP stuff). The implementation couples the IP, TCP and the
5358 +application layers very tightly. To keep the size of the compiled code
5359 +down, this code also features heavy usage of the goto statement.
5361 +The principle is that we have a small buffer, called the uip_buf, in
5362 +which the device driver puts an incoming packet. The TCP/IP stack
5363 +parses the headers in the packet, and calls upon the application. If
5364 +the remote host has sent data to the application, this data is present
5365 +in the uip_buf and the application read the data from there. It is up
5366 +to the application to put this data into a byte stream if needed. The
5367 +application will not be fed with data that is out of sequence.
5369 +If the application whishes to send data to the peer, it should put its
5370 +data into the uip_buf, 40 bytes from the start of the buffer. The
5371 +TCP/IP stack will calculate the checksums, and fill in the necessary
5372 +header fields and finally send the packet back to the peer.
5376 +#include "uipopt.h"
5377 +#include "uip_arch.h"
5379 +/*-----------------------------------------------------------------------------------*/
5380 +/* Variable definitions. */
5383 +/* 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 */
5384 +#if UIP_FIXEDADDR > 0
5385 +const unsigned short int uip_hostaddr[2] =
5386 + {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
5387 + HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
5388 +const unsigned short int uip_arp_draddr[2] =
5389 + {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
5390 + HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
5391 +const unsigned short int uip_arp_netmask[2] =
5392 + {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
5393 + HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
5395 +unsigned short int uip_hostaddr[2];
5396 +unsigned short int uip_arp_draddr[2], uip_arp_netmask[2];
5397 +#endif /* UIP_FIXEDADDR */
5399 +u8_t uip_buf[UIP_BUFSIZE+2]; /* The packet buffer that contains
5400 + incoming packets. */
5401 +volatile u8_t *uip_appdata; /* The uip_appdata pointer points to
5402 + application data. */
5403 +volatile u8_t *uip_sappdata; /* The uip_appdata pointer points to the
5404 + application data which is to be sent. */
5405 +#if UIP_URGDATA > 0
5406 +volatile u8_t *uip_urgdata; /* The uip_urgdata pointer points to
5407 + urgent data (out-of-band data), if
5409 +volatile u8_t uip_urglen, uip_surglen;
5410 +#endif /* UIP_URGDATA > 0 */
5412 +volatile unsigned short int uip_len, uip_slen;
5413 + /* The uip_len is either 8 or 16 bits,
5414 + depending on the maximum packet
5417 +volatile u8_t uip_flags; /* The uip_flags variable is used for
5418 + communication between the TCP/IP stack
5419 + and the application program. */
5420 +struct uip_conn *uip_conn; /* uip_conn always points to the current
5423 +struct uip_conn uip_conns[UIP_CONNS];
5424 + /* The uip_conns array holds all TCP
5426 +unsigned short int uip_listenports[UIP_LISTENPORTS];
5427 + /* The uip_listenports list all currently
5428 + listning ports. */
5430 +struct uip_udp_conn *uip_udp_conn;
5431 +struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
5432 +#endif /* UIP_UDP */
5435 +static unsigned short int ipid; /* Ths ipid variable is an increasing
5436 + number that is used for the IP ID
5439 +static u8_t iss[4]; /* The iss variable is used for the TCP
5440 + initial sequence number. */
5442 +#if UIP_ACTIVE_OPEN
5443 +static unsigned short int lastport; /* Keeps track of the last port used for
5444 + a new connection. */
5445 +#endif /* UIP_ACTIVE_OPEN */
5447 +/* Temporary variables. */
5448 +volatile u8_t uip_acc32[4];
5449 +static u8_t c, opt;
5450 +static unsigned short int tmp16;
5452 +/* Structures and definitions. */
5453 +#define TCP_FIN 0x01
5454 +#define TCP_SYN 0x02
5455 +#define TCP_RST 0x04
5456 +#define TCP_PSH 0x08
5457 +#define TCP_ACK 0x10
5458 +#define TCP_URG 0x20
5459 +#define TCP_CTL 0x3f
5461 +#define ICMP_ECHO_REPLY 0
5462 +#define ICMP_ECHO 8
5465 +#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
5466 +#define FBUF ((uip_tcpip_hdr *)&uip_reassbuf[0])
5467 +#define ICMPBUF ((uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
5468 +#define UDPBUF ((uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
5470 +#if UIP_STATISTICS == 1
5471 +struct uip_stats uip_stat;
5472 +#define UIP_STAT(s) s
5474 +#define UIP_STAT(s)
5475 +#endif /* UIP_STATISTICS == 1 */
5477 +#if UIP_LOGGING == 1
5478 +extern void puts(const char *s);
5479 +#define UIP_LOG(m) puts(m)
5482 +#endif /* UIP_LOGGING == 1 */
5484 +/*-----------------------------------------------------------------------------------*/
5488 + for(c = 0; c < UIP_LISTENPORTS; ++c) {
5489 + uip_listenports[c] = 0;
5491 + for(c = 0; c < UIP_CONNS; ++c) {
5492 + uip_conns[c].tcpstateflags = CLOSED;
5494 +#if UIP_ACTIVE_OPEN
5496 +#endif /* UIP_ACTIVE_OPEN */
5499 + for(c = 0; c < UIP_UDP_CONNS; ++c) {
5500 + uip_udp_conns[c].lport = 0;
5502 +#endif /* UIP_UDP */
5505 + /* IPv4 initialization. */
5506 +#if UIP_FIXEDADDR == 0
5507 + uip_hostaddr[0] = uip_hostaddr[1] = 0;
5508 +#endif /* UIP_FIXEDADDR */
5511 +/*-----------------------------------------------------------------------------------*/
5512 +#if UIP_ACTIVE_OPEN
5514 +uip_connect(unsigned short int *ripaddr, unsigned short int rport)
5516 + register struct uip_conn *conn, *cconn;
5518 + /* Find an unused local port. */
5522 + if(lastport >= 32000) {
5526 + /* Check if this port is already in use, and if so try to find
5528 + for(c = 0; c < UIP_CONNS; ++c) {
5529 + conn = &uip_conns[c];
5530 + if(conn->tcpstateflags != CLOSED &&
5531 + conn->lport == htons(lastport)) {
5538 + for(c = 0; c < UIP_CONNS; ++c) {
5539 + cconn = &uip_conns[c];
5540 + if(cconn->tcpstateflags == CLOSED) {
5544 + if(cconn->tcpstateflags == TIME_WAIT) {
5546 + cconn->timer > uip_conn->timer) {
5556 + conn->tcpstateflags = SYN_SENT;
5558 + conn->snd_nxt[0] = iss[0];
5559 + conn->snd_nxt[1] = iss[1];
5560 + conn->snd_nxt[2] = iss[2];
5561 + conn->snd_nxt[3] = iss[3];
5563 + conn->initialmss = conn->mss = UIP_TCP_MSS;
5565 + conn->len = 1; /* TCP length of the SYN is one. */
5567 + conn->timer = 1; /* Send the SYN next time around. */
5568 + conn->rto = UIP_RTO;
5571 + conn->lport = htons(lastport);
5572 + conn->rport = rport;
5573 + conn->ripaddr[0] = ripaddr[0];
5574 + conn->ripaddr[1] = ripaddr[1];
5578 +#endif /* UIP_ACTIVE_OPEN */
5579 +/*-----------------------------------------------------------------------------------*/
5581 +struct uip_udp_conn *
5582 +uip_udp_new(unsigned short int *ripaddr, unsigned short int rport)
5584 + register struct uip_udp_conn *conn;
5586 + /* Find an unused local port. */
5590 + if(lastport >= 32000) {
5594 + for(c = 0; c < UIP_UDP_CONNS; ++c) {
5595 + if(uip_udp_conns[c].lport == lastport) {
5602 + for(c = 0; c < UIP_UDP_CONNS; ++c) {
5603 + if(uip_udp_conns[c].lport == 0) {
5604 + conn = &uip_udp_conns[c];
5613 + conn->lport = HTONS(lastport);
5614 + conn->rport = HTONS(rport);
5615 + conn->ripaddr[0] = ripaddr[0];
5616 + conn->ripaddr[1] = ripaddr[1];
5620 +#endif /* UIP_UDP */
5621 +/*-----------------------------------------------------------------------------------*/
5623 +uip_unlisten(unsigned short int port)
5625 + for(c = 0; c < UIP_LISTENPORTS; ++c) {
5626 + if(uip_listenports[c] == port) {
5627 + uip_listenports[c] = 0;
5632 +/*-----------------------------------------------------------------------------------*/
5634 +uip_listen(unsigned short int port)
5636 + for(c = 0; c < UIP_LISTENPORTS; ++c) {
5637 + if(uip_listenports[c] == 0) {
5638 + uip_listenports[c] = port;
5643 +/*-----------------------------------------------------------------------------------*/
5644 +/* XXX: IP fragment reassembly: not well-tested. */
5647 +#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
5648 +static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
5649 +static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
5650 +static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
5651 + 0x0f, 0x07, 0x03, 0x01};
5652 +static unsigned short int uip_reasslen;
5653 +static u8_t uip_reassflags;
5654 +#define UIP_REASS_FLAG_LASTFRAG 0x01
5655 +static u8_t uip_reasstmr;
5663 + unsigned short int offset, len;
5664 + unsigned short int i;
5666 + /* If ip_reasstmr is zero, no packet is present in the buffer, so we
5667 + write the IP header of the fragment into the reassembly
5668 + buffer. The timer is updated with the maximum age. */
5669 + if(uip_reasstmr == 0) {
5670 + memcpy(uip_reassbuf, &BUF->vhl, IP_HLEN);
5671 + uip_reasstmr = UIP_REASS_MAXAGE;
5672 + uip_reassflags = 0;
5673 + /* Clear the bitmap. */
5674 + memset(uip_reassbitmap, sizeof(uip_reassbitmap), 0);
5677 + /* Check if the incoming fragment matches the one currently present
5678 + in the reasembly buffer. If so, we proceed with copying the
5679 + fragment into the buffer. */
5680 + if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
5681 + BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
5682 + BUF->destipaddr[0] == FBUF->destipaddr[0] &&
5683 + BUF->destipaddr[1] == FBUF->destipaddr[1] &&
5684 + BUF->ipid[0] == FBUF->ipid[0] &&
5685 + BUF->ipid[1] == FBUF->ipid[1]) {
5687 + len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
5688 + offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
5690 + /* If the offset or the offset + fragment length overflows the
5691 + reassembly buffer, we discard the entire packet. */
5692 + if(offset > UIP_REASS_BUFSIZE ||
5693 + offset + len > UIP_REASS_BUFSIZE) {
5698 + /* Copy the fragment into the reassembly buffer, at the right
5700 + memcpy(&uip_reassbuf[IP_HLEN + offset],
5701 + (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
5704 + /* Update the bitmap. */
5705 + if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
5706 + /* If the two endpoints are in the same byte, we only update
5709 + uip_reassbitmap[offset / (8 * 8)] |=
5710 + bitmap_bits[(offset / 8 ) & 7] &
5711 + ~bitmap_bits[((offset + len) / 8 ) & 7];
5713 + /* If the two endpoints are in different bytes, we update the
5714 + bytes in the endpoints and fill the stuff inbetween with
5716 + uip_reassbitmap[offset / (8 * 8)] |=
5717 + bitmap_bits[(offset / 8 ) & 7];
5718 + for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
5719 + uip_reassbitmap[i] = 0xff;
5721 + uip_reassbitmap[(offset + len) / (8 * 8)] |=
5722 + ~bitmap_bits[((offset + len) / 8 ) & 7];
5725 + /* If this fragment has the More Fragments flag set to zero, we
5726 + know that this is the last fragment, so we can calculate the
5727 + size of the entire packet. We also set the
5728 + IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
5729 + the final fragment. */
5731 + if((BUF->ipoffset[0] & IP_MF) == 0) {
5732 + uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
5733 + uip_reasslen = offset + len;
5736 + /* Finally, we check if we have a full packet in the buffer. We do
5737 + this by checking if we have the last fragment and if all bits
5738 + in the bitmap are set. */
5739 + if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
5740 + /* Check all bytes up to and including all but the last byte in
5742 + for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
5743 + if(uip_reassbitmap[i] != 0xff) {
5747 + /* Check the last byte in the bitmap. It should contain just the
5748 + right amount of bits. */
5749 + if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
5750 + (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
5754 + /* If we have come this far, we have a full packet in the
5755 + buffer, so we allocate a pbuf and copy the packet into it. We
5756 + also reset the timer. */
5758 + memcpy(BUF, FBUF, uip_reasslen);
5760 + /* Pretend to be a "normal" (i.e., not fragmented) IP packet
5762 + BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
5763 + BUF->len[0] = uip_reasslen >> 8;
5764 + BUF->len[1] = uip_reasslen & 0xff;
5765 + BUF->ipchksum = 0;
5766 + BUF->ipchksum = ~(uip_ipchksum());
5768 + return uip_reasslen;
5775 +#endif /* UIP_REASSEMBL */
5776 +/*-----------------------------------------------------------------------------------*/
5778 +uip_add_rcv_nxt(unsigned short int n)
5780 + uip_add32(uip_conn->rcv_nxt, n);
5781 + uip_conn->rcv_nxt[0] = uip_acc32[0];
5782 + uip_conn->rcv_nxt[1] = uip_acc32[1];
5783 + uip_conn->rcv_nxt[2] = uip_acc32[2];
5784 + uip_conn->rcv_nxt[3] = uip_acc32[3];
5786 +/*-----------------------------------------------------------------------------------*/
5788 +uip_process(u8_t flag)
5790 + register struct uip_conn *uip_connr = uip_conn;
5792 + uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
5795 + /* Check if we were invoked because of the perodic timer fireing. */
5796 + if(flag == UIP_TIMER) {
5798 + if(uip_reasstmr != 0) {
5801 +#endif /* UIP_REASSEMBLY */
5802 + /* Increase the initial sequence number. */
5803 + if(++iss[3] == 0) {
5804 + if(++iss[2] == 0) {
5805 + if(++iss[1] == 0) {
5811 + if(uip_connr->tcpstateflags == TIME_WAIT ||
5812 + uip_connr->tcpstateflags == FIN_WAIT_2) {
5813 + ++(uip_connr->timer);
5814 + if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
5815 + uip_connr->tcpstateflags = CLOSED;
5817 + } else if(uip_connr->tcpstateflags != CLOSED) {
5818 + /* If the connection has outstanding data, we increase the
5819 + connection's timer and see if it has reached the RTO value
5820 + in which case we retransmit. */
5821 + if(uip_outstanding(uip_connr)) {
5822 + if(uip_connr->timer-- == 0) {
5823 + if(uip_connr->nrtx == UIP_MAXRTX ||
5824 + ((uip_connr->tcpstateflags == SYN_SENT ||
5825 + uip_connr->tcpstateflags == SYN_RCVD) &&
5826 + uip_connr->nrtx == UIP_MAXSYNRTX)) {
5827 + uip_connr->tcpstateflags = CLOSED;
5829 + /* We call UIP_APPCALL() with uip_flags set to
5830 + UIP_TIMEDOUT to inform the application that the
5831 + connection has timed out. */
5832 + uip_flags = UIP_TIMEDOUT;
5835 + /* We also send a reset packet to the remote host. */
5836 + BUF->flags = TCP_RST | TCP_ACK;
5837 + goto tcp_send_nodata;
5840 + /* Exponential backoff. */
5841 + uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
5844 + ++(uip_connr->nrtx);
5846 + /* Ok, so we need to retransmit. We do this differently
5847 + depending on which state we are in. In ESTABLISHED, we
5848 + call upon the application so that it may prepare the
5849 + data for the retransmit. In SYN_RCVD, we resend the
5850 + SYNACK that we sent earlier and in LAST_ACK we have to
5851 + retransmit our FINACK. */
5852 + UIP_STAT(++uip_stat.tcp.rexmit);
5853 + switch(uip_connr->tcpstateflags & TS_MASK) {
5855 + /* In the SYN_RCVD state, we should retransmit our
5857 + goto tcp_send_synack;
5859 +#if UIP_ACTIVE_OPEN
5861 + /* In the SYN_SENT state, we retransmit out SYN. */
5863 + goto tcp_send_syn;
5864 +#endif /* UIP_ACTIVE_OPEN */
5867 + /* In the ESTABLISHED state, we call upon the application
5868 + to do the actual retransmit after which we jump into
5869 + the code for sending out the packet (the apprexmit
5873 + uip_flags = UIP_REXMIT;
5880 + /* In all these states we should retransmit a FINACK. */
5881 + goto tcp_send_finack;
5885 + } else if((uip_connr->tcpstateflags & TS_MASK) == ESTABLISHED) {
5886 + /* If there was no need for a retransmission, we poll the
5887 + application for new data. */
5890 + uip_flags = UIP_POLL;
5898 + if(flag == UIP_UDP_TIMER) {
5899 + if(uip_udp_conn->lport != 0) {
5900 + uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
5901 + uip_len = uip_slen = 0;
5902 + uip_flags = UIP_POLL;
5903 + UIP_UDP_APPCALL();
5911 + /* This is where the input processing starts. */
5912 + UIP_STAT(++uip_stat.ip.recv);
5915 + /* Start of IPv4 input header processing code. */
5917 + /* Check validity of the IP header. */
5918 + if(BUF->vhl != 0x45) { /* IP version and header length. */
5919 + UIP_STAT(++uip_stat.ip.drop);
5920 + UIP_STAT(++uip_stat.ip.vhlerr);
5921 + UIP_LOG("ip: invalid version or header length.");
5925 + /* Check the size of the packet. If the size reported to us in
5926 + uip_len doesn't match the size reported in the IP header, there
5927 + has been a transmission error and we drop the packet. */
5929 + if(BUF->len[0] != (uip_len >> 8)) { /* IP length, high byte. */
5930 + uip_len = (uip_len & 0xff) | (BUF->len[0] << 8);
5932 + if(BUF->len[1] != (uip_len & 0xff)) { /* IP length, low byte. */
5933 + uip_len = (uip_len & 0xff00) | BUF->len[1];
5936 + /* Check the fragment flag. */
5937 + if((BUF->ipoffset[0] & 0x3f) != 0 ||
5938 + BUF->ipoffset[1] != 0) {
5940 + uip_len = uip_reass();
5941 + if(uip_len == 0) {
5945 + UIP_STAT(++uip_stat.ip.drop);
5946 + UIP_STAT(++uip_stat.ip.fragerr);
5947 + UIP_LOG("ip: fragment dropped.");
5949 +#endif /* UIP_REASSEMBLY */
5952 + /* If we are configured to use ping IP address configuration and
5953 + hasn't been assigned an IP address yet, we accept all ICMP
5955 +#if UIP_PINGADDRCONF
5956 + if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
5957 + if(BUF->proto == UIP_PROTO_ICMP) {
5958 + UIP_LOG("ip: possible ping config packet received.");
5961 + UIP_LOG("ip: packet dropped since no address assigned.");
5965 +#endif /* UIP_PINGADDRCONF */
5967 + /* Check if the packet is destined for our IP address. */
5968 + if(BUF->destipaddr[0] != uip_hostaddr[0]) {
5969 + UIP_STAT(++uip_stat.ip.drop);
5970 + UIP_LOG("ip: packet not for us.");
5973 + if(BUF->destipaddr[1] != uip_hostaddr[1]) {
5974 + UIP_STAT(++uip_stat.ip.drop);
5975 + UIP_LOG("ip: packet not for us.");
5979 + if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
5981 + UIP_STAT(++uip_stat.ip.drop);
5982 + UIP_STAT(++uip_stat.ip.chkerr);
5983 + UIP_LOG("ip: bad checksum.");
5987 + if(BUF->proto == UIP_PROTO_TCP) /* Check for TCP packet. If so, jump
5988 + to the tcp_input label. */
5992 + if(BUF->proto == UIP_PROTO_UDP)
5994 +#endif /* UIP_UDP */
5996 + if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
5998 + UIP_STAT(++uip_stat.ip.drop);
5999 + UIP_STAT(++uip_stat.ip.protoerr);
6000 + UIP_LOG("ip: neither tcp nor icmp.");
6005 + UIP_STAT(++uip_stat.icmp.recv);
6007 + /* ICMP echo (i.e., ping) processing. This is simple, we only change
6008 + the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
6009 + checksum before we return the packet. */
6010 + if(ICMPBUF->type != ICMP_ECHO) {
6011 + UIP_STAT(++uip_stat.icmp.drop);
6012 + UIP_STAT(++uip_stat.icmp.typeerr);
6013 + UIP_LOG("icmp: not icmp echo.");
6017 + /* If we are configured to use ping IP address assignment, we use
6018 + the destination IP address of this ping packet and assign it to
6020 +#if UIP_PINGADDRCONF
6021 + if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
6022 + uip_hostaddr[0] = BUF->destipaddr[0];
6023 + uip_hostaddr[1] = BUF->destipaddr[1];
6025 +#endif /* UIP_PINGADDRCONF */
6027 + ICMPBUF->type = ICMP_ECHO_REPLY;
6029 + if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
6030 + ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
6032 + ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
6035 + /* Swap IP addresses. */
6036 + tmp16 = BUF->destipaddr[0];
6037 + BUF->destipaddr[0] = BUF->srcipaddr[0];
6038 + BUF->srcipaddr[0] = tmp16;
6039 + tmp16 = BUF->destipaddr[1];
6040 + BUF->destipaddr[1] = BUF->srcipaddr[1];
6041 + BUF->srcipaddr[1] = tmp16;
6043 + UIP_STAT(++uip_stat.icmp.sent);
6046 + /* End of IPv4 input header processing code. */
6050 + /* UDP input processing. */
6052 + /* UDP processing is really just a hack. We don't do anything to the
6053 + UDP/IP headers, but let the UDP application do all the hard
6054 + work. If the application sets uip_slen, it has a packet to
6056 +#if UIP_UDP_CHECKSUMS
6057 + if(uip_udpchksum() != 0xffff) {
6058 + UIP_STAT(++uip_stat.udp.drop);
6059 + UIP_STAT(++uip_stat.udp.chkerr);
6060 + UIP_LOG("udp: bad checksum.");
6063 +#endif /* UIP_UDP_CHECKSUMS */
6065 + /* Demultiplex this UDP packet between the UDP "connections". */
6066 + for(uip_udp_conn = &uip_udp_conns[0];
6067 + uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
6069 + if(uip_udp_conn->lport != 0 &&
6070 + UDPBUF->destport == uip_udp_conn->lport &&
6071 + (uip_udp_conn->rport == 0 ||
6072 + UDPBUF->srcport == uip_udp_conn->rport) &&
6073 + BUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] &&
6074 + BUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) {
6081 + uip_len = uip_len - 28;
6082 + uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
6083 + uip_flags = UIP_NEWDATA;
6085 + UIP_UDP_APPCALL();
6087 + if(uip_slen == 0) {
6090 + uip_len = uip_slen + 28;
6092 + BUF->len[0] = (uip_len >> 8);
6093 + BUF->len[1] = (uip_len & 0xff);
6095 + BUF->proto = UIP_PROTO_UDP;
6097 + UDPBUF->udplen = HTONS(uip_slen + 8);
6098 + UDPBUF->udpchksum = 0;
6099 +#if UIP_UDP_CHECKSUMS
6100 + /* Calculate UDP checksum. */
6101 + UDPBUF->udpchksum = ~(uip_udpchksum());
6102 + if(UDPBUF->udpchksum == 0) {
6103 + UDPBUF->udpchksum = 0xffff;
6105 +#endif /* UIP_UDP_CHECKSUMS */
6107 + BUF->srcport = uip_udp_conn->lport;
6108 + BUF->destport = uip_udp_conn->rport;
6110 + BUF->srcipaddr[0] = uip_hostaddr[0];
6111 + BUF->srcipaddr[1] = uip_hostaddr[1];
6112 + BUF->destipaddr[0] = uip_udp_conn->ripaddr[0];
6113 + BUF->destipaddr[1] = uip_udp_conn->ripaddr[1];
6115 + uip_appdata = &uip_buf[UIP_LLH_LEN + 40];
6116 + goto ip_send_nolen;
6117 +#endif /* UIP_UDP */
6119 + /* TCP input processing. */
6121 + UIP_STAT(++uip_stat.tcp.recv);
6123 + /* Start of TCP input header processing code. */
6125 + if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
6127 + UIP_STAT(++uip_stat.tcp.drop);
6128 + UIP_STAT(++uip_stat.tcp.chkerr);
6129 + UIP_LOG("tcp: bad checksum.");
6133 + /* Demultiplex this segment. */
6134 + /* First check any active connections. */
6135 + for(uip_connr = &uip_conns[0]; uip_connr < &uip_conns[UIP_CONNS]; ++uip_connr) {
6136 + if(uip_connr->tcpstateflags != CLOSED &&
6137 + BUF->destport == uip_connr->lport &&
6138 + BUF->srcport == uip_connr->rport &&
6139 + BUF->srcipaddr[0] == uip_connr->ripaddr[0] &&
6140 + BUF->srcipaddr[1] == uip_connr->ripaddr[1]) {
6145 + /* If we didn't find and active connection that expected the packet,
6146 + either this packet is an old duplicate, or this is a SYN packet
6147 + destined for a connection in LISTEN. If the SYN flag isn't set,
6148 + it is an old packet and we send a RST. */
6149 + if((BUF->flags & TCP_CTL) != TCP_SYN)
6152 + tmp16 = BUF->destport;
6153 + /* Next, check listening connections. */
6154 + for(c = 0; c < UIP_LISTENPORTS; ++c) {
6155 + if(tmp16 == uip_listenports[c])
6156 + goto found_listen;
6159 + /* No matching connection found, so we send a RST packet. */
6160 + UIP_STAT(++uip_stat.tcp.synrst);
6163 + /* We do not send resets in response to resets. */
6164 + if(BUF->flags & TCP_RST)
6167 + UIP_STAT(++uip_stat.tcp.rst);
6169 + BUF->flags = TCP_RST | TCP_ACK;
6171 + BUF->tcpoffset = 5 << 4;
6173 + /* Flip the seqno and ackno fields in the TCP header. */
6174 + c = BUF->seqno[3];
6175 + BUF->seqno[3] = BUF->ackno[3];
6176 + BUF->ackno[3] = c;
6178 + c = BUF->seqno[2];
6179 + BUF->seqno[2] = BUF->ackno[2];
6180 + BUF->ackno[2] = c;
6182 + c = BUF->seqno[1];
6183 + BUF->seqno[1] = BUF->ackno[1];
6184 + BUF->ackno[1] = c;
6186 + c = BUF->seqno[0];
6187 + BUF->seqno[0] = BUF->ackno[0];
6188 + BUF->ackno[0] = c;
6190 + /* We also have to increase the sequence number we are
6191 + acknowledging. If the least significant byte overflowed, we need
6192 + to propagate the carry to the other bytes as well. */
6193 + if(++BUF->ackno[3] == 0) {
6194 + if(++BUF->ackno[2] == 0) {
6195 + if(++BUF->ackno[1] == 0) {
6201 + /* Swap port numbers. */
6202 + tmp16 = BUF->srcport;
6203 + BUF->srcport = BUF->destport;
6204 + BUF->destport = tmp16;
6206 + /* Swap IP addresses. */
6207 + tmp16 = BUF->destipaddr[0];
6208 + BUF->destipaddr[0] = BUF->srcipaddr[0];
6209 + BUF->srcipaddr[0] = tmp16;
6210 + tmp16 = BUF->destipaddr[1];
6211 + BUF->destipaddr[1] = BUF->srcipaddr[1];
6212 + BUF->srcipaddr[1] = tmp16;
6215 + /* And send out the RST packet! */
6216 + goto tcp_send_noconn;
6218 + /* This label will be jumped to if we matched the incoming packet
6219 + with a connection in LISTEN. In that case, we should create a new
6220 + connection and send a SYNACK in return. */
6222 + /* First we check if there are any connections avaliable. Unused
6223 + connections are kept in the same table as used connections, but
6224 + unused ones have the tcpstate set to CLOSED. Also, connections in
6225 + TIME_WAIT are kept track of and we'll use the oldest one if no
6226 + CLOSED connections are found. Thanks to Eddie C. Dost for a very
6227 + nice algorithm for the TIME_WAIT search. */
6229 + for(c = 0; c < UIP_CONNS; ++c) {
6230 + if(uip_conns[c].tcpstateflags == CLOSED) {
6231 + uip_connr = &uip_conns[c];
6234 + if(uip_conns[c].tcpstateflags == TIME_WAIT) {
6235 + if(uip_connr == 0 ||
6236 + uip_conns[c].timer > uip_connr->timer) {
6237 + uip_connr = &uip_conns[c];
6242 + if(uip_connr == 0) {
6243 + /* All connections are used already, we drop packet and hope that
6244 + the remote end will retransmit the packet at a time when we
6245 + have more spare connections. */
6246 + UIP_STAT(++uip_stat.tcp.syndrop);
6247 + UIP_LOG("tcp: found no unused connections.");
6250 + uip_conn = uip_connr;
6252 + /* Fill in the necessary fields for the new connection. */
6253 + uip_connr->rto = uip_connr->timer = UIP_RTO;
6254 + uip_connr->sa = 0;
6255 + uip_connr->sv = 4;
6256 + uip_connr->nrtx = 0;
6257 + uip_connr->lport = BUF->destport;
6258 + uip_connr->rport = BUF->srcport;
6259 + uip_connr->ripaddr[0] = BUF->srcipaddr[0];
6260 + uip_connr->ripaddr[1] = BUF->srcipaddr[1];
6261 + uip_connr->tcpstateflags = SYN_RCVD;
6263 + uip_connr->snd_nxt[0] = iss[0];
6264 + uip_connr->snd_nxt[1] = iss[1];
6265 + uip_connr->snd_nxt[2] = iss[2];
6266 + uip_connr->snd_nxt[3] = iss[3];
6267 + uip_connr->len = 1;
6269 + /* rcv_nxt should be the seqno from the incoming packet + 1. */
6270 + uip_connr->rcv_nxt[3] = BUF->seqno[3];
6271 + uip_connr->rcv_nxt[2] = BUF->seqno[2];
6272 + uip_connr->rcv_nxt[1] = BUF->seqno[1];
6273 + uip_connr->rcv_nxt[0] = BUF->seqno[0];
6274 + uip_add_rcv_nxt(1);
6276 + /* Parse the TCP MSS option, if present. */
6277 + if((BUF->tcpoffset & 0xf0) > 0x50) {
6278 + for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
6279 + opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
6281 + /* End of options. */
6283 + } else if(opt == 0x01) {
6286 + } else if(opt == 0x02 &&
6287 + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
6288 + /* An MSS option with the right option length. */
6289 + tmp16 = ((unsigned short int)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
6290 + (unsigned short int)uip_buf[40 + UIP_LLH_LEN + 3 + c];
6291 + uip_connr->initialmss = uip_connr->mss =
6292 + tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
6294 + /* And we are done processing options. */
6297 + /* All other options have a length field, so that we easily
6298 + can skip past them. */
6299 + if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
6300 + /* If the length field is zero, the options are malformed
6301 + and we don't process them further. */
6304 + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
6309 + /* Our response will be a SYNACK. */
6310 +#if UIP_ACTIVE_OPEN
6312 + BUF->flags = TCP_ACK;
6315 + BUF->flags |= TCP_SYN;
6316 +#else /* UIP_ACTIVE_OPEN */
6318 + BUF->flags = TCP_SYN | TCP_ACK;
6319 +#endif /* UIP_ACTIVE_OPEN */
6321 + /* We send out the TCP Maximum Segment Size option with our
6323 + BUF->optdata[0] = 2;
6324 + BUF->optdata[1] = 4;
6325 + BUF->optdata[2] = (UIP_TCP_MSS) / 256;
6326 + BUF->optdata[3] = (UIP_TCP_MSS) & 255;
6328 + BUF->tcpoffset = 6 << 4;
6331 + /* This label will be jumped to if we found an active connection. */
6333 + uip_conn = uip_connr;
6336 + /* We do a very naive form of TCP reset processing; we just accept
6337 + any RST and kill our connection. We should in fact check if the
6338 + sequence number of this reset is wihtin our advertised window
6339 + before we accept the reset. */
6340 + if(BUF->flags & TCP_RST) {
6341 + uip_connr->tcpstateflags = CLOSED;
6342 + UIP_LOG("tcp: got reset, aborting connection.");
6343 + uip_flags = UIP_ABORT;
6347 + /* Calculated the length of the data, if the application has sent
6348 + any data to us. */
6349 + c = (BUF->tcpoffset >> 4) << 2;
6350 + /* uip_len will contain the length of the actual TCP data. This is
6351 + calculated by subtracing the length of the TCP header (in
6352 + c) and the length of the IP header (20 bytes). */
6353 + uip_len = uip_len - c - 20;
6355 + /* First, check if the sequence number of the incoming packet is
6356 + what we're expecting next. If not, we send out an ACK with the
6357 + correct numbers in. */
6359 + (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
6360 + BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
6361 + BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
6362 + BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
6363 + goto tcp_send_ack;
6366 + /* Next, check if the incoming segment acknowledges any outstanding
6367 + data. If so, we update the sequence number, reset the length of
6368 + the outstanding data, calculate RTT estimations, and reset the
6369 + retransmission timer. */
6370 + if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
6371 + uip_add32(uip_connr->snd_nxt, uip_connr->len);
6372 + if(BUF->ackno[0] == uip_acc32[0] &&
6373 + BUF->ackno[1] == uip_acc32[1] &&
6374 + BUF->ackno[2] == uip_acc32[2] &&
6375 + BUF->ackno[3] == uip_acc32[3]) {
6376 + /* Update sequence number. */
6377 + uip_connr->snd_nxt[0] = uip_acc32[0];
6378 + uip_connr->snd_nxt[1] = uip_acc32[1];
6379 + uip_connr->snd_nxt[2] = uip_acc32[2];
6380 + uip_connr->snd_nxt[3] = uip_acc32[3];
6383 + /* Do RTT estimation, unless we have done retransmissions. */
6384 + if(uip_connr->nrtx == 0) {
6386 + m = uip_connr->rto - uip_connr->timer;
6387 + /* This is taken directly from VJs original code in his paper */
6388 + m = m - (uip_connr->sa >> 3);
6389 + uip_connr->sa += m;
6393 + m = m - (uip_connr->sv >> 2);
6394 + uip_connr->sv += m;
6395 + uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
6398 + /* Set the acknowledged flag. */
6399 + uip_flags = UIP_ACKDATA;
6400 + /* Reset the retransmission timer. */
6401 + uip_connr->timer = uip_connr->rto;
6406 + /* Do different things depending on in what state the connection is. */
6407 + switch(uip_connr->tcpstateflags & TS_MASK) {
6408 + /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
6409 + implemented, since we force the application to close when the
6410 + peer sends a FIN (hence the application goes directly from
6411 + ESTABLISHED to LAST_ACK). */
6413 + /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
6414 + we are waiting for an ACK that acknowledges the data we sent
6415 + out the last time. Therefore, we want to have the UIP_ACKDATA
6416 + flag set. If so, we enter the ESTABLISHED state. */
6417 + if(uip_flags & UIP_ACKDATA) {
6418 + uip_connr->tcpstateflags = ESTABLISHED;
6419 + uip_flags = UIP_CONNECTED;
6420 + uip_connr->len = 0;
6422 + uip_flags |= UIP_NEWDATA;
6423 + uip_add_rcv_nxt(uip_len);
6430 +#if UIP_ACTIVE_OPEN
6432 + /* In SYN_SENT, we wait for a SYNACK that is sent in response to
6433 + our SYN. The rcv_nxt is set to sequence number in the SYNACK
6434 + plus one, and we send an ACK. We move into the ESTABLISHED
6436 + if((uip_flags & UIP_ACKDATA) &&
6437 + BUF->flags == (TCP_SYN | TCP_ACK)) {
6439 + /* Parse the TCP MSS option, if present. */
6440 + if((BUF->tcpoffset & 0xf0) > 0x50) {
6441 + for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
6442 + opt = uip_buf[40 + UIP_LLH_LEN + c];
6444 + /* End of options. */
6446 + } else if(opt == 0x01) {
6449 + } else if(opt == 0x02 &&
6450 + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
6451 + /* An MSS option with the right option length. */
6452 + tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
6453 + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
6454 + uip_connr->initialmss =
6455 + uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
6457 + /* And we are done processing options. */
6460 + /* All other options have a length field, so that we easily
6461 + can skip past them. */
6462 + if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
6463 + /* If the length field is zero, the options are malformed
6464 + and we don't process them further. */
6467 + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
6471 + uip_connr->tcpstateflags = ESTABLISHED;
6472 + uip_connr->rcv_nxt[0] = BUF->seqno[0];
6473 + uip_connr->rcv_nxt[1] = BUF->seqno[1];
6474 + uip_connr->rcv_nxt[2] = BUF->seqno[2];
6475 + uip_connr->rcv_nxt[3] = BUF->seqno[3];
6476 + uip_add_rcv_nxt(1);
6477 + uip_flags = UIP_CONNECTED | UIP_NEWDATA;
6478 + uip_connr->len = 0;
6485 +#endif /* UIP_ACTIVE_OPEN */
6488 + /* In the ESTABLISHED state, we call upon the application to feed
6489 + data into the uip_buf. If the UIP_ACKDATA flag is set, the
6490 + application should put new data into the buffer, otherwise we are
6491 + retransmitting an old segment, and the application should put that
6492 + data into the buffer.
6494 + If the incoming packet is a FIN, we should close the connection on
6495 + this side as well, and we send out a FIN and enter the LAST_ACK
6496 + state. We require that there is no outstanding data; otherwise the
6497 + sequence numbers will be screwed up. */
6499 + if(BUF->flags & TCP_FIN) {
6500 + if(uip_outstanding(uip_connr)) {
6503 + uip_add_rcv_nxt(1 + uip_len);
6504 + uip_flags = UIP_CLOSE;
6506 + uip_flags |= UIP_NEWDATA;
6509 + uip_connr->len = 1;
6510 + uip_connr->tcpstateflags = LAST_ACK;
6511 + uip_connr->nrtx = 0;
6513 + BUF->flags = TCP_FIN | TCP_ACK;
6514 + goto tcp_send_nodata;
6517 + /* Check the URG flag. If this is set, the segment carries urgent
6518 + data that we must pass to the application. */
6519 + if(BUF->flags & TCP_URG) {
6520 +#if UIP_URGDATA > 0
6521 + uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
6522 + if(uip_urglen > uip_len) {
6523 + /* There is more urgent data in the next segment to come. */
6524 + uip_urglen = uip_len;
6526 + uip_add_rcv_nxt(uip_urglen);
6527 + uip_len -= uip_urglen;
6528 + uip_urgdata = uip_appdata;
6529 + uip_appdata += uip_urglen;
6532 +#endif /* UIP_URGDATA > 0 */
6533 + uip_appdata += (BUF->urgp[0] << 8) | BUF->urgp[1];
6534 + uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
6538 + /* If uip_len > 0 we have TCP data in the packet, and we flag this
6539 + by setting the UIP_NEWDATA flag and update the sequence number
6540 + we acknowledge. If the application has stopped the dataflow
6541 + using uip_stop(), we must not accept any data packets from the
6543 + if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
6544 + uip_flags |= UIP_NEWDATA;
6545 + uip_add_rcv_nxt(uip_len);
6548 + /* Check if the available buffer space advertised by the other end
6549 + is smaller than the initial MSS for this connection. If so, we
6550 + set the current MSS to the window size to ensure that the
6551 + application does not send more data than the other end can
6554 + If the remote host advertises a zero window, we set the MSS to
6555 + the initial MSS so that the application will send an entire MSS
6556 + of data. This data will not be acknowledged by the receiver,
6557 + and the application will retransmit it. This is called the
6558 + "persistent timer" and uses the retransmission mechanim.
6560 + tmp16 = ((unsigned short int)BUF->wnd[0] << 8) + (unsigned short int)BUF->wnd[1];
6561 + if(tmp16 > uip_connr->initialmss ||
6563 + tmp16 = uip_connr->initialmss;
6565 + uip_connr->mss = tmp16;
6567 + /* If this packet constitutes an ACK for outstanding data (flagged
6568 + by the UIP_ACKDATA flag, we should call the application since it
6569 + might want to send more data. If the incoming packet had data
6570 + from the peer (as flagged by the UIP_NEWDATA flag), the
6571 + application must also be notified.
6573 + When the application is called, the global variable uip_len
6574 + contains the length of the incoming data. The application can
6575 + access the incoming data through the global pointer
6576 + uip_appdata, which usually points 40 bytes into the uip_buf
6579 + If the application wishes to send any data, this data should be
6580 + put into the uip_appdata and the length of the data should be
6581 + put into uip_len. If the application don't have any data to
6582 + send, uip_len must be set to 0. */
6583 + if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
6589 + if(uip_flags & UIP_ABORT) {
6591 + uip_connr->tcpstateflags = CLOSED;
6592 + BUF->flags = TCP_RST | TCP_ACK;
6593 + goto tcp_send_nodata;
6596 + if(uip_flags & UIP_CLOSE) {
6598 + uip_connr->len = 1;
6599 + uip_connr->tcpstateflags = FIN_WAIT_1;
6600 + uip_connr->nrtx = 0;
6601 + BUF->flags = TCP_FIN | TCP_ACK;
6602 + goto tcp_send_nodata;
6605 + /* If uip_slen > 0, the application has data to be sent. */
6606 + if(uip_slen > 0) {
6608 + /* If the connection has acknowledged data, the contents of
6609 + the ->len variable should be discarded. */
6610 + if((uip_flags & UIP_ACKDATA) != 0) {
6611 + uip_connr->len = 0;
6614 + /* If the ->len variable is non-zero the connection has
6615 + already data in transit and cannot send anymore right
6617 + if(uip_connr->len == 0) {
6619 + /* The application cannot send more than what is allowed by
6620 + the mss (the minumum of the MSS and the available
6622 + if(uip_slen > uip_connr->mss) {
6623 + uip_slen = uip_connr->mss;
6626 + /* Remember how much data we send out now so that we know
6627 + when everything has been acknowledged. */
6628 + uip_connr->len = uip_slen;
6631 + /* If the application already had unacknowledged data, we
6632 + make sure that the application does not send (i.e.,
6633 + retransmit) out more than it previously sent out. */
6634 + uip_slen = uip_connr->len;
6637 + uip_connr->len = 0;
6639 + uip_connr->nrtx = 0;
6641 + uip_appdata = uip_sappdata;
6643 + /* If the application has data to be sent, or if the incoming
6644 + packet had new data in it, we must send out a packet. */
6645 + if(uip_slen > 0 && uip_connr->len > 0) {
6646 + /* Add the length of the IP and TCP headers. */
6647 + uip_len = uip_connr->len + UIP_TCPIP_HLEN;
6648 + /* We always set the ACK flag in response packets. */
6649 + BUF->flags = TCP_ACK | TCP_PSH;
6650 + /* Send the packet. */
6651 + goto tcp_send_noopts;
6653 + /* If there is no data to send, just send out a pure ACK if
6654 + there is newdata. */
6655 + if(uip_flags & UIP_NEWDATA) {
6656 + uip_len = UIP_TCPIP_HLEN;
6657 + BUF->flags = TCP_ACK;
6658 + goto tcp_send_noopts;
6663 + /* We can close this connection if the peer has acknowledged our
6664 + FIN. This is indicated by the UIP_ACKDATA flag. */
6665 + if(uip_flags & UIP_ACKDATA) {
6666 + uip_connr->tcpstateflags = CLOSED;
6667 + uip_flags = UIP_CLOSE;
6673 + /* The application has closed the connection, but the remote host
6674 + hasn't closed its end yet. Thus we do nothing but wait for a
6675 + FIN from the other side. */
6677 + uip_add_rcv_nxt(uip_len);
6679 + if(BUF->flags & TCP_FIN) {
6680 + if(uip_flags & UIP_ACKDATA) {
6681 + uip_connr->tcpstateflags = TIME_WAIT;
6682 + uip_connr->timer = 0;
6683 + uip_connr->len = 0;
6685 + uip_connr->tcpstateflags = CLOSING;
6687 + uip_add_rcv_nxt(1);
6688 + uip_flags = UIP_CLOSE;
6690 + goto tcp_send_ack;
6691 + } else if(uip_flags & UIP_ACKDATA) {
6692 + uip_connr->tcpstateflags = FIN_WAIT_2;
6693 + uip_connr->len = 0;
6697 + goto tcp_send_ack;
6703 + uip_add_rcv_nxt(uip_len);
6705 + if(BUF->flags & TCP_FIN) {
6706 + uip_connr->tcpstateflags = TIME_WAIT;
6707 + uip_connr->timer = 0;
6708 + uip_add_rcv_nxt(1);
6709 + uip_flags = UIP_CLOSE;
6711 + goto tcp_send_ack;
6714 + goto tcp_send_ack;
6719 + goto tcp_send_ack;
6722 + if(uip_flags & UIP_ACKDATA) {
6723 + uip_connr->tcpstateflags = TIME_WAIT;
6724 + uip_connr->timer = 0;
6730 + /* We jump here when we are ready to send the packet, and just want
6731 + to set the appropriate TCP sequence numbers in the TCP header. */
6733 + BUF->flags = TCP_ACK;
6737 + BUF->tcpoffset = 5 << 4;
6739 + /* We're done with the input processing. We are now ready to send a
6740 + reply. Our job is to fill in all the fields of the TCP and IP
6741 + headers before calculating the checksum and finally send the
6743 + BUF->ackno[0] = uip_connr->rcv_nxt[0];
6744 + BUF->ackno[1] = uip_connr->rcv_nxt[1];
6745 + BUF->ackno[2] = uip_connr->rcv_nxt[2];
6746 + BUF->ackno[3] = uip_connr->rcv_nxt[3];
6748 + BUF->seqno[0] = uip_connr->snd_nxt[0];
6749 + BUF->seqno[1] = uip_connr->snd_nxt[1];
6750 + BUF->seqno[2] = uip_connr->snd_nxt[2];
6751 + BUF->seqno[3] = uip_connr->snd_nxt[3];
6753 + BUF->proto = UIP_PROTO_TCP;
6755 + BUF->srcport = uip_connr->lport;
6756 + BUF->destport = uip_connr->rport;
6758 + BUF->srcipaddr[0] = uip_hostaddr[0];
6759 + BUF->srcipaddr[1] = uip_hostaddr[1];
6760 + BUF->destipaddr[0] = uip_connr->ripaddr[0];
6761 + BUF->destipaddr[1] = uip_connr->ripaddr[1];
6764 + if(uip_connr->tcpstateflags & UIP_STOPPED) {
6765 + /* If the connection has issued uip_stop(), we advertise a zero
6766 + window so that the remote host will stop sending data. */
6767 + BUF->wnd[0] = BUF->wnd[1] = 0;
6769 + BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
6770 + BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
6775 + BUF->len[0] = (uip_len >> 8);
6776 + BUF->len[1] = (uip_len & 0xff);
6778 + /* Calculate TCP checksum. */
6779 + BUF->tcpchksum = 0;
6780 + BUF->tcpchksum = ~(uip_tcpchksum());
6786 + BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
6787 + BUF->ttl = UIP_TTL;
6789 + BUF->ipid[0] = ipid >> 8;
6790 + BUF->ipid[1] = ipid & 0xff;
6792 + /* Calculate IP checksum. */
6793 + BUF->ipchksum = 0;
6794 + BUF->ipchksum = ~(uip_ipchksum());
6796 + UIP_STAT(++uip_stat.tcp.sent);
6798 + UIP_STAT(++uip_stat.ip.sent);
6799 + /* Return and let the caller do the actual transmission. */
6805 +/*-----------------------------------------------------------------------------------*/
6806 +/*unsigned short int
6807 +htons(unsigned short int val)
6809 + return HTONS(val);
6811 +/*-----------------------------------------------------------------------------------*/
6814 +++ b/net/uip-0.9/uip.h
6823 + * Header file for the uIP TCP/IP stack.
6824 + * \author Adam Dunkels <adam@dunkels.com>
6826 + * The uIP TCP/IP stack header file contains definitions for a number
6827 + * of C macros that are used by uIP programs as well as internal uIP
6828 + * structures, TCP/IP header structures and function declarations.
6834 + * Copyright (c) 2001-2003, Adam Dunkels.
6835 + * All rights reserved.
6837 + * Redistribution and use in source and binary forms, with or without
6838 + * modification, are permitted provided that the following conditions
6840 + * 1. Redistributions of source code must retain the above copyright
6841 + * notice, this list of conditions and the following disclaimer.
6842 + * 2. Redistributions in binary form must reproduce the above copyright
6843 + * notice, this list of conditions and the following disclaimer in the
6844 + * documentation and/or other materials provided with the distribution.
6845 + * 3. The name of the author may not be used to endorse or promote
6846 + * products derived from this software without specific prior
6847 + * written permission.
6849 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
6850 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6851 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6852 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
6853 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6854 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
6855 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
6856 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
6857 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
6858 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6859 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6861 + * This file is part of the uIP TCP/IP stack.
6863 + * $Id: uip.h,v 1.36.2.7 2003/10/07 13:47:51 adam Exp $
6869 +#include <linux/types.h>
6870 +#include <linux/string.h>
6871 +#include <linux/ctype.h>
6872 +#include <malloc.h>
6873 +#include <common.h>
6876 +#include "uipopt.h"
6878 +/*-----------------------------------------------------------------------------------*/
6879 +/* First, the functions that should be called from the
6880 + * system. Initialization, the periodic timer and incoming packets are
6881 + * handled by the following three functions.
6885 + * \defgroup uipconffunc uIP configuration functions
6888 + * The uIP configuration functions are used for setting run-time
6889 + * parameters in uIP such as IP addresses.
6893 + * Set the IP address of this host.
6895 + * The IP address is represented as a 4-byte array where the first
6896 + * octet of the IP address is put in the first member of the 4-byte
6899 + * \param addr A pointer to a 4-byte representation of the IP address.
6901 + * \hideinitializer
6903 +#define uip_sethostaddr(addr) do { uip_hostaddr[0] = addr[0]; \
6904 + uip_hostaddr[1] = addr[1]; } while(0)
6907 + * Get the IP address of this host.
6909 + * The IP address is represented as a 4-byte array where the first
6910 + * octet of the IP address is put in the first member of the 4-byte
6913 + * \param addr A pointer to a 4-byte array that will be filled in with
6914 + * the currently configured IP address.
6916 + * \hideinitializer
6918 +#define uip_gethostaddr(addr) do { addr[0] = uip_hostaddr[0]; \
6919 + addr[1] = uip_hostaddr[1]; } while(0)
6924 + * \defgroup uipinit uIP initialization functions
6927 + * The uIP initialization functions are used for booting uIP.
6931 + * uIP initialization function.
6933 + * This function should be called at boot up to initilize the uIP
6936 +void uip_init(void);
6941 + * \defgroup uipdevfunc uIP device driver functions
6944 + * These functions are used by a network device driver for interacting
6949 + * Process an incoming packet.
6951 + * This function should be called when the device driver has received
6952 + * a packet from the network. The packet from the device driver must
6953 + * be present in the uip_buf buffer, and the length of the packet
6954 + * should be placed in the uip_len variable.
6956 + * When the function returns, there may be an outbound packet placed
6957 + * in the uip_buf packet buffer. If so, the uip_len variable is set to
6958 + * the length of the packet. If no packet is to be sent out, the
6959 + * uip_len variable is set to 0.
6961 + * The usual way of calling the function is presented by the source
6964 + uip_len = devicedriver_poll();
6968 + devicedriver_send();
6973 + * \note If you are writing a uIP device driver that needs ARP
6974 + * (Address Resolution Protocol), e.g., when running uIP over
6975 + * Ethernet, you will need to call the uIP ARP code before calling
6978 + #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
6979 + uip_len = ethernet_devicedrver_poll();
6981 + if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
6986 + ethernet_devicedriver_send();
6988 + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
6991 + ethernet_devicedriver_send();
6996 + * \hideinitializer
6998 +#define uip_input() uip_process(UIP_DATA)
7001 + * Periodic processing for a connection identified by its number.
7003 + * This function does the necessary periodic processing (timers,
7004 + * polling) for a uIP TCP conneciton, and should be called when the
7005 + * periodic uIP timer goes off. It should be called for every
7006 + * connection, regardless of whether they are open of closed.
7008 + * When the function returns, it may have an outbound packet waiting
7009 + * for service in the uIP packet buffer, and if so the uip_len
7010 + * variable is set to a value larger than zero. The device driver
7011 + * should be called to send out the packet.
7013 + * The ususal way of calling the function is through a for() loop like
7016 + for(i = 0; i < UIP_CONNS; ++i) {
7019 + devicedriver_send();
7024 + * \note If you are writing a uIP device driver that needs ARP
7025 + * (Address Resolution Protocol), e.g., when running uIP over
7026 + * Ethernet, you will need to call the uip_arp_out() function before
7027 + * calling the device driver:
7029 + for(i = 0; i < UIP_CONNS; ++i) {
7033 + ethernet_devicedriver_send();
7038 + * \param conn The number of the connection which is to be periodically polled.
7040 + * \hideinitializer
7042 +#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
7043 + uip_process(UIP_TIMER); } while (0)
7046 + * Periodic processing for a connection identified by a pointer to its structure.
7048 + * Same as uip_periodic() but takes a pointer to the actual uip_conn
7049 + * struct instead of an integer as its argument. This function can be
7050 + * used to force periodic processing of a specific connection.
7052 + * \param conn A pointer to the uip_conn struct for the connection to
7055 + * \hideinitializer
7057 +#define uip_periodic_conn(conn) do { uip_conn = conn; \
7058 + uip_process(UIP_TIMER); } while (0)
7062 + * Periodic processing for a UDP connection identified by its number.
7064 + * This function is essentially the same as uip_prerioic(), but for
7065 + * UDP connections. It is called in a similar fashion as the
7066 + * uip_periodic() function:
7068 + for(i = 0; i < UIP_UDP_CONNS; i++) {
7069 + uip_udp_periodic(i);
7071 + devicedriver_send();
7076 + * \note As for the uip_periodic() function, special care has to be
7077 + * taken when using uIP together with ARP and Ethernet:
7079 + for(i = 0; i < UIP_UDP_CONNS; i++) {
7080 + uip_udp_periodic(i);
7083 + ethernet_devicedriver_send();
7088 + * \param conn The number of the UDP connection to be processed.
7090 + * \hideinitializer
7092 +#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
7093 + uip_process(UIP_UDP_TIMER); } while (0)
7096 + * Periodic processing for a UDP connection identified by a pointer to
7099 + * Same as uip_udp_periodic() but takes a pointer to the actual
7100 + * uip_conn struct instead of an integer as its argument. This
7101 + * function can be used to force periodic processing of a specific
7104 + * \param conn A pointer to the uip_udp_conn struct for the connection
7105 + * to be processed.
7107 + * \hideinitializer
7109 +#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
7110 + uip_process(UIP_UDP_TIMER); } while (0)
7113 +#endif /* UIP_UDP */
7116 + * The uIP packet buffer.
7118 + * The uip_buf array is used to hold incoming and outgoing
7119 + * packets. The device driver should place incoming data into this
7120 + * buffer. When sending data, the device driver should read the link
7121 + * level headers and the TCP/IP headers from this buffer. The size of
7122 + * the link level headers is configured by the UIP_LLH_LEN define.
7124 + * \note The application data need not be placed in this buffer, so
7125 + * the device driver must read it from the place pointed to by the
7126 + * uip_appdata pointer as illustrated by the following example:
7129 + devicedriver_send(void)
7131 + hwsend(&uip_buf[0], UIP_LLH_LEN);
7132 + hwsend(&uip_buf[UIP_LLH_LEN], 40);
7133 + hwsend(uip_appdata, uip_len - 40 - UIP_LLH_LEN);
7137 +extern u8_t uip_buf[UIP_BUFSIZE+2];
7141 +/*-----------------------------------------------------------------------------------*/
7142 +/* Functions that are used by the uIP application program. Opening and
7143 + * closing connections, sending and receiving data, etc. is all
7144 + * handled by the functions below.
7147 + * \defgroup uipappfunc uIP application functions
7150 + * Functions used by an application running of top of uIP.
7154 + * Start listening to the specified port.
7156 + * \note Since this function expects the port number in network byte
7157 + * order, a conversion using HTONS() or htons() is necessary.
7160 + uip_listen(HTONS(80));
7163 + * \param port A 16-bit port number in network byte order.
7165 +void uip_listen(u16_t port);
7168 + * Stop listening to the specified port.
7170 + * \note Since this function expects the port number in network byte
7171 + * order, a conversion using HTONS() or htons() is necessary.
7174 + uip_unlisten(HTONS(80));
7177 + * \param port A 16-bit port number in network byte order.
7179 +void uip_unlisten(u16_t port);
7182 + * Connect to a remote host using TCP.
7184 + * This function is used to start a new connection to the specified
7185 + * port on the specied host. It allocates a new connection identifier,
7186 + * sets the connection to the SYN_SENT state and sets the
7187 + * retransmission timer to 0. This will cause a TCP SYN segment to be
7188 + * sent out the next time this connection is periodically processed,
7189 + * which usually is done within 0.5 seconds after the call to
7192 + * \note This function is avaliable only if support for active open
7193 + * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h.
7195 + * \note Since this function requires the port number to be in network
7196 + * byte order, a convertion using HTONS() or htons() is necessary.
7201 + uip_ipaddr(ipaddr, 192,168,1,2);
7202 + uip_connect(ipaddr, HTONS(80));
7205 + * \param ripaddr A pointer to a 4-byte array representing the IP
7206 + * address of the remote hot.
7208 + * \param port A 16-bit port number in network byte order.
7210 + * \return A pointer to the uIP connection identifier for the new connection,
7211 + * or NULL if no connection could be allocated.
7214 +struct uip_conn *uip_connect(u16_t *ripaddr, u16_t port);
7221 + * Check if a connection has outstanding (i.e., unacknowledged) data.
7223 + * \param conn A pointer to the uip_conn structure for the connection.
7225 + * \hideinitializer
7227 +#define uip_outstanding(conn) ((conn)->len)
7230 + * Send data on the current connection.
7232 + * This function is used to send out a single segment of TCP
7233 + * data. Only applications that have been invoked by uIP for event
7234 + * processing can send data.
7236 + * The amount of data that actually is sent out after a call to this
7237 + * funcion is determined by the maximum amount of data TCP allows. uIP
7238 + * will automatically crop the data so that only the appropriate
7239 + * amount of data is sent. The function uip_mss() can be used to query
7240 + * uIP for the amount of data that actually will be sent.
7242 + * \note This function does not guarantee that the sent data will
7243 + * arrive at the destination. If the data is lost in the network, the
7244 + * application will be invoked with the uip_rexmit() event being
7245 + * set. The application will then have to resend the data using this
7248 + * \param data A pointer to the data which is to be sent.
7250 + * \param len The maximum amount of data bytes to be sent.
7252 + * \hideinitializer
7254 +#define uip_send(data, len) do { uip_sappdata = (data); uip_slen = (len);} while(0)
7257 + * The length of any incoming data that is currently avaliable (if avaliable)
7258 + * in the uip_appdata buffer.
7260 + * The test function uip_data() must first be used to check if there
7261 + * is any data available at all.
7263 + * \hideinitializer
7265 +#define uip_datalen() uip_len
7268 + * The length of any out-of-band data (urgent data) that has arrived
7269 + * on the connection.
7271 + * \note The configuration parameter UIP_URGDATA must be set for this
7272 + * function to be enabled.
7274 + * \hideinitializer
7276 +#define uip_urgdatalen() uip_urglen
7279 + * Close the current connection.
7281 + * This function will close the current connection in a nice way.
7283 + * \hideinitializer
7285 +#define uip_close() (uip_flags = UIP_CLOSE)
7288 + * Abort the current connection.
7290 + * This function will abort (reset) the current connection, and is
7291 + * usually used when an error has occured that prevents using the
7292 + * uip_close() function.
7294 + * \hideinitializer
7296 +#define uip_abort() (uip_flags = UIP_ABORT)
7299 + * Tell the sending host to stop sending data.
7301 + * This function will close our receiver's window so that we stop
7302 + * receiving data for the current connection.
7304 + * \hideinitializer
7306 +#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED)
7309 + * Find out if the current connection has been previously stopped with
7312 + * \hideinitializer
7314 +#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED)
7317 + * Restart the current connection, if is has previously been stopped
7318 + * with uip_stop().
7320 + * This function will open the receiver's window again so that we
7321 + * start receiving data for the current connection.
7323 + * \hideinitializer
7325 +#define uip_restart() do { uip_flags |= UIP_NEWDATA; \
7326 + uip_conn->tcpstateflags &= ~UIP_STOPPED; \
7330 +/* uIP tests that can be made to determine in what state the current
7331 + connection is, and what the application function should do. */
7334 + * Is new incoming data available?
7336 + * Will reduce to non-zero if there is new data for the application
7337 + * present at the uip_appdata pointer. The size of the data is
7338 + * avaliable through the uip_len variable.
7340 + * \hideinitializer
7342 +#define uip_newdata() (uip_flags & UIP_NEWDATA)
7345 + * Has previously sent data been acknowledged?
7347 + * Will reduce to non-zero if the previously sent data has been
7348 + * acknowledged by the remote host. This means that the application
7349 + * can send new data.
7351 + * \hideinitializer
7353 +#define uip_acked() (uip_flags & UIP_ACKDATA)
7356 + * Has the connection just been connected?
7358 + * Reduces to non-zero if the current connection has been connected to
7359 + * a remote host. This will happen both if the connection has been
7360 + * actively opened (with uip_connect()) or passively opened (with
7363 + * \hideinitializer
7365 +#define uip_connected() (uip_flags & UIP_CONNECTED)
7368 + * Has the connection been closed by the other end?
7370 + * Is non-zero if the connection has been closed by the remote
7371 + * host. The application may then do the necessary clean-ups.
7373 + * \hideinitializer
7375 +#define uip_closed() (uip_flags & UIP_CLOSE)
7378 + * Has the connection been aborted by the other end?
7380 + * Non-zero if the current connection has been aborted (reset) by the
7383 + * \hideinitializer
7385 +#define uip_aborted() (uip_flags & UIP_ABORT)
7388 + * Has the connection timed out?
7390 + * Non-zero if the current connection has been aborted due to too many
7391 + * retransmissions.
7393 + * \hideinitializer
7395 +#define uip_timedout() (uip_flags & UIP_TIMEDOUT)
7398 + * Do we need to retransmit previously data?
7400 + * Reduces to non-zero if the previously sent data has been lost in
7401 + * the network, and the application should retransmit it. The
7402 + * application should send the exact same data as it did the last
7403 + * time, using the uip_send() function.
7405 + * \hideinitializer
7407 +#define uip_rexmit() (uip_flags & UIP_REXMIT)
7410 + * Is the connection being polled by uIP?
7412 + * Is non-zero if the reason the application is invoked is that the
7413 + * current connection has been idle for a while and should be
7416 + * The polling event can be used for sending data without having to
7417 + * wait for the remote host to send data.
7419 + * \hideinitializer
7421 +#define uip_poll() (uip_flags & UIP_POLL)
7424 + * Get the initial maxium segment size (MSS) of the current
7427 + * \hideinitializer
7429 +#define uip_initialmss() (uip_conn->initialmss)
7432 + * Get the current maxium segment size that can be sent on the current
7435 + * The current maxiumum segment size that can be sent on the
7436 + * connection is computed from the receiver's window and the MSS of
7437 + * the connection (which also is available by calling
7438 + * uip_initialmss()).
7440 + * \hideinitializer
7442 +#define uip_mss() (uip_conn->mss)
7445 + * Set up a new UDP connection.
7447 + * \param ripaddr A pointer to a 4-byte structure representing the IP
7448 + * address of the remote host.
7450 + * \param rport The remote port number in network byte order.
7452 + * \return The uip_udp_conn structure for the new connection or NULL
7453 + * if no connection could be allocated.
7455 +struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport);
7458 + * Removed a UDP connection.
7460 + * \param conn A pointer to the uip_udp_conn structure for the connection.
7462 + * \hideinitializer
7464 +#define uip_udp_remove(conn) (conn)->lport = 0
7467 + * Send a UDP datagram of length len on the current connection.
7469 + * This function can only be called in response to a UDP event (poll
7470 + * or newdata). The data must be present in the uip_buf buffer, at the
7471 + * place pointed to by the uip_appdata pointer.
7473 + * \param len The length of the data in the uip_buf buffer.
7475 + * \hideinitializer
7477 +#define uip_udp_send(len) uip_slen = (len)
7481 +/* uIP convenience and converting functions. */
7484 + * \defgroup uipconvfunc uIP conversion functions
7487 + * These functions can be used for converting between different data
7488 + * formats used by uIP.
7492 + * Pack an IP address into a 4-byte array which is used by uIP to
7493 + * represent IP addresses.
7499 + uip_ipaddr(&ipaddr, 192,168,1,2);
7502 + * \param addr A pointer to a 4-byte array that will be filled in with
7504 + * \param addr0 The first octet of the IP address.
7505 + * \param addr1 The second octet of the IP address.
7506 + * \param addr2 The third octet of the IP address.
7507 + * \param addr3 The forth octet of the IP address.
7509 + * \hideinitializer
7511 +#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
7512 + (addr)[0] = HTONS(((addr0) << 8) | (addr1)); \
7513 + (addr)[1] = HTONS(((addr2) << 8) | (addr3)); \
7517 + * Convert 16-bit quantity from host byte order to network byte order.
7519 + * This macro is primarily used for converting constants from host
7520 + * byte order to network byte order. For converting variables to
7521 + * network byte order, use the htons() function instead.
7523 + * \hideinitializer
7526 +# if BYTE_ORDER == BIG_ENDIAN
7527 +# define HTONS(n) (n)
7528 +# else /* BYTE_ORDER == BIG_ENDIAN */
7529 +# define HTONS(n) ((((u16_t)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8))
7530 +# endif /* BYTE_ORDER == BIG_ENDIAN */
7534 + * Convert 16-bit quantity from host byte order to network byte order.
7536 + * This function is primarily used for converting variables from host
7537 + * byte order to network byte order. For converting constants to
7538 + * network byte order, use the HTONS() macro instead.
7541 +u16_t htons(u16_t val);
7547 + * Pointer to the application data in the packet buffer.
7549 + * This pointer points to the application data when the application is
7550 + * called. If the application wishes to send data, the application may
7551 + * use this space to write the data into before calling uip_send().
7553 +extern volatile u8_t *uip_appdata;
7554 +extern volatile u8_t *uip_sappdata;
7556 +#if UIP_URGDATA > 0
7557 +/* u8_t *uip_urgdata:
7559 + * This pointer points to any urgent data that has been received. Only
7560 + * present if compiled with support for urgent data (UIP_URGDATA).
7562 +extern volatile u8_t *uip_urgdata;
7563 +#endif /* UIP_URGDATA > 0 */
7566 +/* u[8|16]_t uip_len:
7568 + * When the application is called, uip_len contains the length of any
7569 + * new data that has been received from the remote host. The
7570 + * application should set this variable to the size of any data that
7571 + * the application wishes to send. When the network device driver
7572 + * output function is called, uip_len should contain the length of the
7573 + * outgoing packet.
7575 +extern volatile u16_t uip_len, uip_slen;
7577 +#if UIP_URGDATA > 0
7578 +extern volatile u8_t uip_urglen, uip_surglen;
7579 +#endif /* UIP_URGDATA > 0 */
7583 + * Representation of a uIP TCP connection.
7585 + * The uip_conn structure is used for identifying a connection. All
7586 + * but one field in the structure are to be considered read-only by an
7587 + * application. The only exception is the appstate field whos purpose
7588 + * is to let the application store application-specific state (e.g.,
7589 + * file pointers) for the connection. The size of this field is
7590 + * configured in the "uipopt.h" header file.
7593 + u16_t ripaddr[2]; /**< The IP address of the remote host. */
7595 + u16_t lport; /**< The local TCP port, in network byte order. */
7596 + u16_t rport; /**< The local remote TCP port, in network byte
7599 + u8_t rcv_nxt[4]; /**< The sequence number that we expect to
7601 + u8_t snd_nxt[4]; /**< The sequence number that was last sent by
7603 + u16_t len; /**< Length of the data that was previously sent. */
7604 + u16_t mss; /**< Current maximum segment size for the
7606 + u16_t initialmss; /**< Initial maximum segment size for the
7608 + u8_t sa; /**< Retransmission time-out calculation state
7610 + u8_t sv; /**< Retransmission time-out calculation state
7612 + u8_t rto; /**< Retransmission time-out. */
7613 + u8_t tcpstateflags; /**< TCP state and flags. */
7614 + u8_t timer; /**< The retransmission timer. */
7615 + u8_t nrtx; /**< The number of retransmissions for the last
7618 + /** The application state. */
7619 + u8_t appstate[UIP_APPSTATE_SIZE];
7623 +/* Pointer to the current connection. */
7624 +extern struct uip_conn *uip_conn;
7625 +/* The array containing all uIP connections. */
7626 +extern struct uip_conn uip_conns[UIP_CONNS];
7628 + * \addtogroup uiparch
7633 + * 4-byte array used for the 32-bit sequence number calculations.
7635 +extern volatile u8_t uip_acc32[4];
7642 + * Representation of a uIP UDP connection.
7644 +struct uip_udp_conn {
7645 + u16_t ripaddr[2]; /**< The IP address of the remote peer. */
7646 + u16_t lport; /**< The local port number in network byte order. */
7647 + u16_t rport; /**< The remote port number in network byte order. */
7650 +extern struct uip_udp_conn *uip_udp_conn;
7651 +extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
7652 +#endif /* UIP_UDP */
7655 + * The structure holding the TCP/IP statistics that are gathered if
7656 + * UIP_STATISTICS is set to 1.
7661 + uip_stats_t drop; /**< Number of dropped packets at the IP
7663 + uip_stats_t recv; /**< Number of received packets at the IP
7665 + uip_stats_t sent; /**< Number of sent packets at the IP
7667 + uip_stats_t vhlerr; /**< Number of packets dropped due to wrong
7668 + IP version or header length. */
7669 + uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
7670 + IP length, high byte. */
7671 + uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
7672 + IP length, low byte. */
7673 + uip_stats_t fragerr; /**< Number of packets dropped since they
7674 + were IP fragments. */
7675 + uip_stats_t chkerr; /**< Number of packets dropped due to IP
7676 + checksum errors. */
7677 + uip_stats_t protoerr; /**< Number of packets dropped since they
7678 + were neither ICMP, UDP nor TCP. */
7679 + } ip; /**< IP statistics. */
7681 + uip_stats_t drop; /**< Number of dropped ICMP packets. */
7682 + uip_stats_t recv; /**< Number of received ICMP packets. */
7683 + uip_stats_t sent; /**< Number of sent ICMP packets. */
7684 + uip_stats_t typeerr; /**< Number of ICMP packets with a wrong
7686 + } icmp; /**< ICMP statistics. */
7688 + uip_stats_t drop; /**< Number of dropped TCP segments. */
7689 + uip_stats_t recv; /**< Number of recived TCP segments. */
7690 + uip_stats_t sent; /**< Number of sent TCP segments. */
7691 + uip_stats_t chkerr; /**< Number of TCP segments with a bad
7693 + uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK
7695 + uip_stats_t rst; /**< Number of recevied TCP RST (reset) segments. */
7696 + uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */
7697 + uip_stats_t syndrop; /**< Number of dropped SYNs due to too few
7698 + connections was avaliable. */
7699 + uip_stats_t synrst; /**< Number of SYNs for closed ports,
7700 + triggering a RST. */
7701 + } tcp; /**< TCP statistics. */
7705 + * The uIP TCP/IP statistics.
7707 + * This is the variable in which the uIP TCP/IP statistics are gathered.
7709 +extern struct uip_stats uip_stat;
7712 +/*-----------------------------------------------------------------------------------*/
7713 +/* All the stuff below this point is internal to uIP and should not be
7714 + * used directly by an application or by a device driver.
7716 +/*-----------------------------------------------------------------------------------*/
7719 + * When the application is called, uip_flags will contain the flags
7720 + * that are defined in this file. Please read below for more
7723 +extern volatile u8_t uip_flags;
7725 +/* The following flags may be set in the global variable uip_flags
7726 + before calling the application callback. The UIP_ACKDATA and
7727 + UIP_NEWDATA flags may both be set at the same time, whereas the
7728 + others are mutualy exclusive. Note that these flags should *NOT* be
7729 + accessed directly, but through the uIP functions/macros. */
7731 +#define UIP_ACKDATA 1 /* Signifies that the outstanding data was
7732 + acked and the application should send
7733 + out new data instead of retransmitting
7735 +#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent
7737 +#define UIP_REXMIT 4 /* Tells the application to retransmit the
7738 + data that was last sent. */
7739 +#define UIP_POLL 8 /* Used for polling the application, to
7740 + check if the application has data that
7741 + it wants to send. */
7742 +#define UIP_CLOSE 16 /* The remote host has closed the
7743 + connection, thus the connection has
7744 + gone away. Or the application signals
7745 + that it wants to close the
7747 +#define UIP_ABORT 32 /* The remote host has aborted the
7748 + connection, thus the connection has
7749 + gone away. Or the application signals
7750 + that it wants to abort the
7752 +#define UIP_CONNECTED 64 /* We have got a connection from a remote
7753 + host and have set up a new connection
7754 + for it, or an active connection has
7755 + been successfully established. */
7757 +#define UIP_TIMEDOUT 128 /* The connection has been aborted due to
7758 + too many retransmissions. */
7761 +/* uip_process(flag):
7763 + * The actual uIP function which does all the work.
7765 +void uip_process(u8_t flag);
7767 +/* The following flags are passed as an argument to the uip_process()
7768 + function. They are used to distinguish between the two cases where
7769 + uip_process() is called. It can be called either because we have
7770 + incoming data that should be processed, or because the periodic
7771 + timer has fired. */
7773 +#define UIP_DATA 1 /* Tells uIP that there is incoming data in
7774 + the uip_buf buffer. The length of the
7775 + data is stored in the global variable
7777 +#define UIP_TIMER 2 /* Tells uIP that the periodic timer has
7780 +#define UIP_UDP_TIMER 3
7781 +#endif /* UIP_UDP */
7783 +/* The TCP states used in the uip_conn->tcpstateflags. */
7787 +#define ESTABLISHED 3
7788 +#define FIN_WAIT_1 4
7789 +#define FIN_WAIT_2 5
7791 +#define TIME_WAIT 7
7795 +#define UIP_STOPPED 16
7797 +#define UIP_TCPIP_HLEN 40
7799 +/* The TCP and IP headers. */
7810 + u16_t srcipaddr[2],
7826 +/* The ICMP and IP headers. */
7837 + u16_t srcipaddr[2],
7839 + /* ICMP (echo) header. */
7846 +/* The UDP and IP headers. */
7857 + u16_t srcipaddr[2],
7867 +#define UIP_PROTO_ICMP 1
7868 +#define UIP_PROTO_TCP 6
7869 +#define UIP_PROTO_UDP 17
7872 +extern const u16_t uip_hostaddr[2];
7873 +#else /* UIP_FIXEDADDR */
7874 +extern u16_t uip_hostaddr[2];
7875 +#endif /* UIP_FIXEDADDR */
7877 +#endif /* __UIP_H__ */
7883 +++ b/net/uip-0.9/uip_arch.c
7886 + * Copyright (c) 2001, Adam Dunkels.
7887 + * All rights reserved.
7889 + * Redistribution and use in source and binary forms, with or without
7890 + * modification, are permitted provided that the following conditions
7892 + * 1. Redistributions of source code must retain the above copyright
7893 + * notice, this list of conditions and the following disclaimer.
7894 + * 2. Redistributions in binary form must reproduce the above copyright
7895 + * notice, this list of conditions and the following disclaimer in the
7896 + * documentation and/or other materials provided with the distribution.
7897 + * 3. The name of the author may not be used to endorse or promote
7898 + * products derived from this software without specific prior
7899 + * written permission.
7901 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
7902 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7903 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7904 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
7905 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7906 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
7907 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
7908 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
7909 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
7910 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7911 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7913 + * This file is part of the uIP TCP/IP stack.
7915 + * $Id: uip_arch.c,v 1.2.2.1 2003/10/04 22:54:17 adam Exp $
7921 +#include "uip_arch.h"
7923 +#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
7924 +#define IP_PROTO_TCP 6
7926 +/*-----------------------------------------------------------------------------------*/
7928 +uip_add32(u8_t *op32, u16_t op16)
7931 + uip_acc32[3] = op32[3] + (op16 & 0xff);
7932 + uip_acc32[2] = op32[2] + (op16 >> 8);
7933 + uip_acc32[1] = op32[1];
7934 + uip_acc32[0] = op32[0];
7936 + if(uip_acc32[2] < (op16 >> 8)) {
7938 + if(uip_acc32[1] == 0) {
7944 + if(uip_acc32[3] < (op16 & 0xff)) {
7946 + if(uip_acc32[2] == 0) {
7948 + if(uip_acc32[1] == 0) {
7954 +/*-----------------------------------------------------------------------------------*/
7956 +uip_chksum(u16_t *sdata, u16_t len)
7960 + for(acc = 0; len > 1; len -= 2) {
7962 + if(acc < *sdata) {
7963 + /* Overflow, so we add the carry to acc (i.e., increase by
7970 + /* add up any odd byte */
7972 + acc += htons(((u16_t)(*(u8_t *)sdata)) << 8);
7973 + if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) {
7980 +/*-----------------------------------------------------------------------------------*/
7984 + return uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN], 20);
7986 +/*-----------------------------------------------------------------------------------*/
7988 +uip_tcpchksum(void)
7993 + /* Compute the checksum of the TCP header. */
7994 + hsum = uip_chksum((u16_t *)&uip_buf[20 + UIP_LLH_LEN], 20);
7996 + /* Compute the checksum of the data in the TCP packet and add it to
7997 + the TCP header checksum. */
7998 + sum = uip_chksum((u16_t *)uip_appdata,
7999 + (u16_t)(((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 40)));
8001 + if((sum += hsum) < hsum) {
8005 + if((sum += BUF->srcipaddr[0]) < BUF->srcipaddr[0]) {
8008 + if((sum += BUF->srcipaddr[1]) < BUF->srcipaddr[1]) {
8011 + if((sum += BUF->destipaddr[0]) < BUF->destipaddr[0]) {
8014 + if((sum += BUF->destipaddr[1]) < BUF->destipaddr[1]) {
8017 + if((sum += (u16_t)htons((u16_t)IP_PROTO_TCP)) < (u16_t)htons((u16_t)IP_PROTO_TCP)) {
8021 + hsum = (u16_t)htons((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 20);
8023 + if((sum += hsum) < hsum) {
8029 +/*-----------------------------------------------------------------------------------*/
8031 +++ b/net/uip-0.9/uip_arch.h
8034 + * \defgroup uiparch Architecture specific uIP functions
8037 + * The functions in the architecture specific module implement the IP
8038 + * check sum and 32-bit additions.
8040 + * The IP checksum calculation is the most computationally expensive
8041 + * operation in the TCP/IP stack and it therefore pays off to
8042 + * implement this in efficient assembler. The purpose of the uip-arch
8043 + * module is to let the checksum functions to be implemented in
8044 + * architecture specific assembler.
8050 + * Declarations of architecture specific functions.
8051 + * \author Adam Dunkels <adam@dunkels.com>
8055 + * Copyright (c) 2001, Adam Dunkels.
8056 + * All rights reserved.
8058 + * Redistribution and use in source and binary forms, with or without
8059 + * modification, are permitted provided that the following conditions
8061 + * 1. Redistributions of source code must retain the above copyright
8062 + * notice, this list of conditions and the following disclaimer.
8063 + * 2. Redistributions in binary form must reproduce the above copyright
8064 + * notice, this list of conditions and the following disclaimer in the
8065 + * documentation and/or other materials provided with the distribution.
8066 + * 3. The name of the author may not be used to endorse or promote
8067 + * products derived from this software without specific prior
8068 + * written permission.
8070 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
8071 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8072 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8073 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
8074 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8075 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
8076 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8077 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
8078 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
8079 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8080 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8082 + * This file is part of the uIP TCP/IP stack.
8084 + * $Id: uip_arch.h,v 1.1.2.2 2003/10/06 15:10:22 adam Exp $
8088 +#ifndef __UIP_ARCH_H__
8089 +#define __UIP_ARCH_H__
8094 + * Carry out a 32-bit addition.
8096 + * Because not all architectures for which uIP is intended has native
8097 + * 32-bit arithmetic, uIP uses an external C function for doing the
8098 + * required 32-bit additions in the TCP protocol processing. This
8099 + * function should add the two arguments and place the result in the
8100 + * global variable uip_acc32.
8102 + * \note The 32-bit integer pointed to by the op32 parameter and the
8103 + * result in the uip_acc32 variable are in network byte order (big
8106 + * \param op32 A pointer to a 4-byte array representing a 32-bit
8107 + * integer in network byte order (big endian).
8109 + * \param op16 A 16-bit integer in host byte order.
8111 +void uip_add32(u8_t *op32, u16_t op16);
8114 + * Calculate the Internet checksum over a buffer.
8116 + * The Internet checksum is the one's complement of the one's
8117 + * complement sum of all 16-bit words in the buffer.
8121 + * \note This function is not called in the current version of uIP,
8122 + * but future versions might make use of it.
8124 + * \param buf A pointer to the buffer over which the checksum is to be
8127 + * \param len The length of the buffer over which the checksum is to
8130 + * \return The Internet checksum of the buffer.
8132 +u16_t uip_chksum(u16_t *buf, u16_t len);
8135 + * Calculate the IP header checksum of the packet header in uip_buf.
8137 + * The IP header checksum is the Internet checksum of the 20 bytes of
8140 + * \return The IP header checksum of the IP header in the uip_buf
8143 +u16_t uip_ipchksum(void);
8146 + * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
8148 + * The TCP checksum is the Internet checksum of data contents of the
8149 + * TCP segment, and a pseudo-header as defined in RFC793.
8151 + * \note The uip_appdata pointer that points to the packet data may
8152 + * point anywhere in memory, so it is not possible to simply calculate
8153 + * the Internet checksum of the contents of the uip_buf buffer.
8155 + * \return The TCP checksum of the TCP segment in uip_buf and pointed
8156 + * to by uip_appdata.
8158 +u16_t uip_tcpchksum(void);
8162 +#endif /* __UIP_ARCH_H__ */
8164 +++ b/net/uip-0.9/uip_arp.c
8172 + * \defgroup uiparp uIP Address Resolution Protocol
8175 + * The Address Resolution Protocol ARP is used for mapping between IP
8176 + * addresses and link level addresses such as the Ethernet MAC
8177 + * addresses. ARP uses broadcast queries to ask for the link level
8178 + * address of a known IP address and the host which is configured with
8179 + * the IP address for which the query was meant, will respond with its
8180 + * link level address.
8182 + * \note This ARP implementation only supports Ethernet.
8187 + * Implementation of the ARP Address Resolution Protocol.
8188 + * \author Adam Dunkels <adam@dunkels.com>
8193 + * Copyright (c) 2001-2003, Adam Dunkels.
8194 + * All rights reserved.
8196 + * Redistribution and use in source and binary forms, with or without
8197 + * modification, are permitted provided that the following conditions
8199 + * 1. Redistributions of source code must retain the above copyright
8200 + * notice, this list of conditions and the following disclaimer.
8201 + * 2. Redistributions in binary form must reproduce the above copyright
8202 + * notice, this list of conditions and the following disclaimer in the
8203 + * documentation and/or other materials provided with the distribution.
8204 + * 3. The name of the author may not be used to endorse or promote
8205 + * products derived from this software without specific prior
8206 + * written permission.
8208 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
8209 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8210 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8211 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
8212 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8213 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
8214 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8215 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
8216 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
8217 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8218 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8220 + * This file is part of the uIP TCP/IP stack.
8222 + * $Id: uip_arp.c,v 1.7.2.3 2003/10/06 22:42:30 adam Exp $
8227 +#include "uip_arp.h"
8230 + struct uip_eth_hdr ethhdr;
8236 + struct uip_eth_addr shwaddr;
8238 + struct uip_eth_addr dhwaddr;
8243 + struct uip_eth_hdr ethhdr;
8253 + u16_t srcipaddr[2],
8257 +#define ARP_REQUEST 1
8258 +#define ARP_REPLY 2
8260 +#define ARP_HWTYPE_ETH 1
8264 + struct uip_eth_addr ethaddr;
8268 +struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
8275 +static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
8276 +static u16_t ipaddr[2];
8279 +static u8_t arptime;
8280 +static u8_t tmpage;
8282 +#define BUF ((struct arp_hdr *)&uip_buf[0])
8283 +#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
8284 +/*-----------------------------------------------------------------------------------*/
8286 + * Initialize the ARP module.
8289 +/*-----------------------------------------------------------------------------------*/
8293 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
8294 + memset(arp_table[i].ipaddr, 0, 4);
8297 +/*-----------------------------------------------------------------------------------*/
8299 + * Periodic ARP processing function.
8301 + * This function performs periodic timer processing in the ARP module
8302 + * and should be called at regular intervals. The recommended interval
8303 + * is 10 seconds between the calls.
8306 +/*-----------------------------------------------------------------------------------*/
8308 +uip_arp_timer(void)
8310 + struct arp_entry *tabptr;
8313 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
8314 + tabptr = &arp_table[i];
8315 + if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
8316 + arptime - tabptr->time >= UIP_ARP_MAXAGE) {
8317 + memset(tabptr->ipaddr, 0, 4);
8322 +/*-----------------------------------------------------------------------------------*/
8324 +uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
8326 + register struct arp_entry *tabptr;
8327 + /* Walk through the ARP mapping table and try to find an entry to
8328 + update. If none is found, the IP -> MAC address mapping is
8329 + inserted in the ARP table. */
8330 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
8332 + tabptr = &arp_table[i];
8333 + /* Only check those entries that are actually in use. */
8334 + if(tabptr->ipaddr[0] != 0 &&
8335 + tabptr->ipaddr[1] != 0) {
8337 + /* Check if the source IP address of the incoming packet matches
8338 + the IP address in this ARP table entry. */
8339 + if(ipaddr[0] == tabptr->ipaddr[0] &&
8340 + ipaddr[1] == tabptr->ipaddr[1]) {
8342 + /* An old entry found, update this and return. */
8343 + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
8344 + tabptr->time = arptime;
8351 + /* If we get here, no existing ARP table entry was found, so we
8354 + /* First, we try to find an unused entry in the ARP table. */
8355 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
8356 + tabptr = &arp_table[i];
8357 + if(tabptr->ipaddr[0] == 0 &&
8358 + tabptr->ipaddr[1] == 0) {
8363 + /* If no unused entry is found, we try to find the oldest entry and
8365 + if(i == UIP_ARPTAB_SIZE) {
8368 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
8369 + tabptr = &arp_table[i];
8370 + if(arptime - tabptr->time > tmpage) {
8371 + tmpage = arptime - tabptr->time;
8378 + /* Now, i is the ARP table entry which we will fill with the new
8380 + memcpy(tabptr->ipaddr, ipaddr, 4);
8381 + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
8382 + tabptr->time = arptime;
8384 +/*-----------------------------------------------------------------------------------*/
8386 + * ARP processing for incoming IP packets
8388 + * This function should be called by the device driver when an IP
8389 + * packet has been received. The function will check if the address is
8390 + * in the ARP cache, and if so the ARP cache entry will be
8391 + * refreshed. If no ARP cache entry was found, a new one is created.
8393 + * This function expects an IP packet with a prepended Ethernet header
8394 + * in the uip_buf[] buffer, and the length of the packet in the global
8395 + * variable uip_len.
8397 +/*-----------------------------------------------------------------------------------*/
8401 + uip_len -= sizeof(struct uip_eth_hdr);
8403 + /* Only insert/update an entry if the source IP address of the
8404 + incoming IP packet comes from a host on the local network. */
8405 + if((IPBUF->srcipaddr[0] & uip_arp_netmask[0]) !=
8406 + (uip_hostaddr[0] & uip_arp_netmask[0])) {
8409 + if((IPBUF->srcipaddr[1] & uip_arp_netmask[1]) !=
8410 + (uip_hostaddr[1] & uip_arp_netmask[1])) {
8413 + uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
8417 +/*-----------------------------------------------------------------------------------*/
8419 + * ARP processing for incoming ARP packets.
8421 + * This function should be called by the device driver when an ARP
8422 + * packet has been received. The function will act differently
8423 + * depending on the ARP packet type: if it is a reply for a request
8424 + * that we previously sent out, the ARP cache will be filled in with
8425 + * the values from the ARP reply. If the incoming ARP packet is an ARP
8426 + * request for our IP address, an ARP reply packet is created and put
8427 + * into the uip_buf[] buffer.
8429 + * When the function returns, the value of the global variable uip_len
8430 + * indicates whether the device driver should send out a packet or
8431 + * not. If uip_len is zero, no packet should be sent. If uip_len is
8432 + * non-zero, it contains the length of the outbound packet that is
8433 + * present in the uip_buf[] buffer.
8435 + * This function expects an ARP packet with a prepended Ethernet
8436 + * header in the uip_buf[] buffer, and the length of the packet in the
8437 + * global variable uip_len.
8439 +/*-----------------------------------------------------------------------------------*/
8441 +uip_arp_arpin(void)
8444 + if(uip_len < sizeof(struct arp_hdr)) {
8451 + switch(BUF->opcode) {
8452 + case HTONS(ARP_REQUEST):
8453 + /* ARP request. If it asked for our address, we send out a
8455 + if(BUF->dipaddr[0] == uip_hostaddr[0] &&
8456 + BUF->dipaddr[1] == uip_hostaddr[1]) {
8457 + /* The reply opcode is 2. */
8458 + BUF->opcode = HTONS(2);
8460 + memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
8461 + memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
8462 + memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
8463 + memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
8465 + BUF->dipaddr[0] = BUF->sipaddr[0];
8466 + BUF->dipaddr[1] = BUF->sipaddr[1];
8467 + BUF->sipaddr[0] = uip_hostaddr[0];
8468 + BUF->sipaddr[1] = uip_hostaddr[1];
8470 + BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
8471 + uip_len = sizeof(struct arp_hdr);
8474 + case HTONS(ARP_REPLY):
8475 + /* ARP reply. We insert or update the ARP table if it was meant
8477 + if(BUF->dipaddr[0] == uip_hostaddr[0] &&
8478 + BUF->dipaddr[1] == uip_hostaddr[1]) {
8480 + uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
8487 +/*-----------------------------------------------------------------------------------*/
8489 + * Prepend Ethernet header to an outbound IP packet and see if we need
8490 + * to send out an ARP request.
8492 + * This function should be called before sending out an IP packet. The
8493 + * function checks the destination IP address of the IP packet to see
8494 + * what Ethernet MAC address that should be used as a destination MAC
8495 + * address on the Ethernet.
8497 + * If the destination IP address is in the local network (determined
8498 + * by logical ANDing of netmask and our IP address), the function
8499 + * checks the ARP cache to see if an entry for the destination IP
8500 + * address is found. If so, an Ethernet header is prepended and the
8501 + * function returns. If no ARP cache entry is found for the
8502 + * destination IP address, the packet in the uip_buf[] is replaced by
8503 + * an ARP request packet for the IP address. The IP packet is dropped
8504 + * and it is assumed that they higher level protocols (e.g., TCP)
8505 + * eventually will retransmit the dropped packet.
8507 + * If the destination IP address is not on the local network, the IP
8508 + * address of the default router is used instead.
8510 + * When the function returns, a packet is present in the uip_buf[]
8511 + * buffer, and the length of the packet is in the global variable
8514 +/*-----------------------------------------------------------------------------------*/
8518 + struct arp_entry *tabptr;
8519 + /* Find the destination IP address in the ARP table and construct
8520 + the Ethernet header. If the destination IP addres isn't on the
8521 + local network, we use the default router's IP address instead.
8523 + If not ARP table entry is found, we overwrite the original IP
8524 + packet with an ARP request for the IP address. */
8526 + /* Check if the destination address is on the local network. */
8527 + if((IPBUF->destipaddr[0] & uip_arp_netmask[0]) !=
8528 + (uip_hostaddr[0] & uip_arp_netmask[0]) ||
8529 + (IPBUF->destipaddr[1] & uip_arp_netmask[1]) !=
8530 + (uip_hostaddr[1] & uip_arp_netmask[1])) {
8531 + /* Destination address was not on the local network, so we need to
8532 + use the default router's IP address instead of the destination
8533 + address when determining the MAC address. */
8534 + ipaddr[0] = uip_arp_draddr[0];
8535 + ipaddr[1] = uip_arp_draddr[1];
8537 + /* Else, we use the destination IP address. */
8538 + ipaddr[0] = IPBUF->destipaddr[0];
8539 + ipaddr[1] = IPBUF->destipaddr[1];
8542 + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
8543 + tabptr = &arp_table[i];
8544 + if(ipaddr[0] == tabptr->ipaddr[0] &&
8545 + ipaddr[1] == tabptr->ipaddr[1])
8549 + if(i == UIP_ARPTAB_SIZE) {
8550 + /* The destination address was not in our ARP table, so we
8551 + overwrite the IP packet with an ARP request. */
8553 + memset(BUF->ethhdr.dest.addr, 0xff, 6);
8554 + memset(BUF->dhwaddr.addr, 0x00, 6);
8555 + memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
8556 + memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
8558 + BUF->dipaddr[0] = ipaddr[0];
8559 + BUF->dipaddr[1] = ipaddr[1];
8560 + BUF->sipaddr[0] = uip_hostaddr[0];
8561 + BUF->sipaddr[1] = uip_hostaddr[1];
8562 + BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
8563 + BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
8564 + BUF->protocol = HTONS(UIP_ETHTYPE_IP);
8566 + BUF->protolen = 4;
8567 + BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
8569 + uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
8571 + uip_len = sizeof(struct arp_hdr);
8575 + /* Build an ethernet header. */
8576 + memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
8577 + memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
8579 + IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
8581 + uip_len += sizeof(struct uip_eth_hdr);
8583 +/*-----------------------------------------------------------------------------------*/
8588 +++ b/net/uip-0.9/uip_arp.h
8596 + * \addtogroup uiparp
8602 + * Macros and definitions for the ARP module.
8603 + * \author Adam Dunkels <adam@dunkels.com>
8608 + * Copyright (c) 2001-2003, Adam Dunkels.
8609 + * All rights reserved.
8611 + * Redistribution and use in source and binary forms, with or without
8612 + * modification, are permitted provided that the following conditions
8614 + * 1. Redistributions of source code must retain the above copyright
8615 + * notice, this list of conditions and the following disclaimer.
8616 + * 2. Redistributions in binary form must reproduce the above copyright
8617 + * notice, this list of conditions and the following disclaimer in the
8618 + * documentation and/or other materials provided with the distribution.
8619 + * 3. The name of the author may not be used to endorse or promote
8620 + * products derived from this software without specific prior
8621 + * written permission.
8623 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
8624 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8625 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8626 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
8627 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8628 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
8629 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8630 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
8631 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
8632 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8633 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8635 + * This file is part of the uIP TCP/IP stack.
8637 + * $Id: uip_arp.h,v 1.3.2.2 2003/10/06 15:10:22 adam Exp $
8641 +#ifndef __UIP_ARP_H__
8642 +#define __UIP_ARP_H__
8648 + * Representation of a 48-bit Ethernet address.
8650 +struct uip_eth_addr {
8654 +extern struct uip_eth_addr uip_ethaddr;
8657 + * The Ethernet header.
8659 +struct uip_eth_hdr {
8660 + struct uip_eth_addr dest;
8661 + struct uip_eth_addr src;
8665 +#define UIP_ETHTYPE_ARP 0x0806
8666 +#define UIP_ETHTYPE_IP 0x0800
8667 +#define UIP_ETHTYPE_IP6 0x86dd
8670 +/* The uip_arp_init() function must be called before any of the other
8672 +void uip_arp_init(void);
8674 +/* The uip_arp_ipin() function should be called whenever an IP packet
8675 + arrives from the Ethernet. This function refreshes the ARP table or
8676 + inserts a new mapping if none exists. The function assumes that an
8677 + IP packet with an Ethernet header is present in the uip_buf buffer
8678 + and that the length of the packet is in the uip_len variable. */
8679 +void uip_arp_ipin(void);
8681 +/* The uip_arp_arpin() should be called when an ARP packet is received
8682 + by the Ethernet driver. This function also assumes that the
8683 + Ethernet frame is present in the uip_buf buffer. When the
8684 + uip_arp_arpin() function returns, the contents of the uip_buf
8685 + buffer should be sent out on the Ethernet if the uip_len variable
8687 +void uip_arp_arpin(void);
8689 +/* The uip_arp_out() function should be called when an IP packet
8690 + should be sent out on the Ethernet. This function creates an
8691 + Ethernet header before the IP header in the uip_buf buffer. The
8692 + Ethernet header will have the correct Ethernet MAC destination
8693 + address filled in if an ARP table entry for the destination IP
8694 + address (or the IP address of the default router) is present. If no
8695 + such table entry is found, the IP packet is overwritten with an ARP
8696 + request and we rely on TCP to retransmit the packet that was
8697 + overwritten. In any case, the uip_len variable holds the length of
8698 + the Ethernet frame that should be transmitted. */
8699 +void uip_arp_out(void);
8701 +/* The uip_arp_timer() function should be called every ten seconds. It
8702 + is responsible for flushing old entries in the ARP table. */
8703 +void uip_arp_timer(void);
8708 + * \addtogroup uipconffunc
8713 + * Set the default router's IP address.
8715 + * \param addr A pointer to a 4-byte array containing the IP address
8716 + * of the default router.
8718 + * \hideinitializer
8720 +#define uip_setdraddr(addr) do { uip_arp_draddr[0] = addr[0]; \
8721 + uip_arp_draddr[1] = addr[1]; } while(0)
8724 + * Set the netmask.
8726 + * \param addr A pointer to a 4-byte array containing the IP address
8729 + * \hideinitializer
8731 +#define uip_setnetmask(addr) do { uip_arp_netmask[0] = addr[0]; \
8732 + uip_arp_netmask[1] = addr[1]; } while(0)
8736 + * Get the default router's IP address.
8738 + * \param addr A pointer to a 4-byte array that will be filled in with
8739 + * the IP address of the default router.
8741 + * \hideinitializer
8743 +#define uip_getdraddr(addr) do { addr[0] = uip_arp_draddr[0]; \
8744 + addr[1] = uip_arp_draddr[1]; } while(0)
8747 + * Get the netmask.
8749 + * \param addr A pointer to a 4-byte array that will be filled in with
8750 + * the value of the netmask.
8752 + * \hideinitializer
8754 +#define uip_getnetmask(addr) do { addr[0] = uip_arp_netmask[0]; \
8755 + addr[1] = uip_arp_netmask[1]; } while(0)
8759 + * Specifiy the Ethernet MAC address.
8761 + * The ARP code needs to know the MAC address of the Ethernet card in
8762 + * order to be able to respond to ARP queries and to generate working
8763 + * Ethernet headers.
8765 + * \note This macro only specifies the Ethernet MAC address to the ARP
8766 + * code. It cannot be used to change the MAC address of the Ethernet
8769 + * \param eaddr A pointer to a struct uip_eth_addr containing the
8770 + * Ethernet MAC address of the Ethernet card.
8772 + * \hideinitializer
8774 +#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \
8775 + uip_ethaddr.addr[1] = eaddr.addr[1];\
8776 + uip_ethaddr.addr[2] = eaddr.addr[2];\
8777 + uip_ethaddr.addr[3] = eaddr.addr[3];\
8778 + uip_ethaddr.addr[4] = eaddr.addr[4];\
8779 + uip_ethaddr.addr[5] = eaddr.addr[5];} while(0)
8784 + * \internal Internal variables that are set using the macros
8785 + * uip_setdraddr and uip_setnetmask.
8787 +extern u16_t uip_arp_draddr[2], uip_arp_netmask[2];
8788 +#endif /* __UIP_ARP_H__ */
8792 +++ b/net/uip-0.9/uipopt.h
8795 + * \defgroup uipopt Configuration options for uIP
8798 + * uIP is configured using the per-project configuration file
8799 + * "uipopt.h". This file contains all compile-time options for uIP and
8800 + * should be tweaked to match each specific project. The uIP
8801 + * distribution contains a documented example "uipopt.h" that can be
8802 + * copied and modified for each project.
8807 + * Configuration options for uIP.
8808 + * \author Adam Dunkels <adam@dunkels.com>
8810 + * This file is used for tweaking various configuration options for
8811 + * uIP. You should make a copy of this file into one of your project's
8812 + * directories instead of editing this example "uipopt.h" file that
8813 + * comes with the uIP distribution.
8817 + * Copyright (c) 2001-2003, Adam Dunkels.
8818 + * All rights reserved.
8820 + * Redistribution and use in source and binary forms, with or without
8821 + * modification, are permitted provided that the following conditions
8823 + * 1. Redistributions of source code must retain the above copyright
8824 + * notice, this list of conditions and the following disclaimer.
8825 + * 2. Redistributions in binary form must reproduce the above copyright
8826 + * notice, this list of conditions and the following disclaimer in the
8827 + * documentation and/or other materials provided with the distribution.
8828 + * 3. The name of the author may not be used to endorse or promote
8829 + * products derived from this software without specific prior
8830 + * written permission.
8832 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
8833 + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8834 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8835 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
8836 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8837 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
8838 + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8839 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
8840 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
8841 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8842 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8844 + * This file is part of the uIP TCP/IP stack.
8846 + * $Id: uipopt.h,v 1.16.2.5 2003/10/07 13:22:51 adam Exp $
8850 +#ifndef __UIPOPT_H__
8851 +#define __UIPOPT_H__
8853 +/*------------------------------------------------------------------------------*/
8855 + * \defgroup uipopttypedef uIP type definitions
8860 + * The 8-bit unsigned data type.
8862 + * This may have to be tweaked for your particular compiler. "unsigned
8863 + * char" works for most compilers.
8865 +typedef unsigned char u8_t;
8868 + * The 16-bit unsigned data type.
8870 + * This may have to be tweaked for your particular compiler. "unsigned
8871 + * short" works for most compilers.
8873 +typedef unsigned short u16_t;
8876 + * The statistics data type.
8878 + * This datatype determines how high the statistics counters are able
8881 +typedef unsigned short uip_stats_t;
8885 +/*------------------------------------------------------------------------------*/
8888 + * \defgroup uipoptstaticconf Static configuration options
8891 + * These configuration options can be used for setting the IP address
8892 + * settings statically, but only if UIP_FIXEDADDR is set to 1. The
8893 + * configuration options for a specific node includes IP address,
8894 + * netmask and default router as well as the Ethernet address. The
8895 + * netmask, default router and Ethernet address are appliciable only
8896 + * if uIP should be run over Ethernet.
8898 + * All of these should be changed to suit your project.
8902 + * Determines if uIP should use a fixed IP address or not.
8904 + * If uIP should use a fixed IP address, the settings are set in the
8905 + * uipopt.h file. If not, the macros uip_sethostaddr(),
8906 + * uip_setdraddr() and uip_setnetmask() should be used instead.
8908 + * \hideinitializer
8910 +#define UIP_FIXEDADDR 0
8913 + * Ping IP address asignment.
8915 + * uIP uses a "ping" packets for setting its own IP address if this
8916 + * option is set. If so, uIP will start with an empty IP address and
8917 + * the destination IP address of the first incoming "ping" (ICMP echo)
8918 + * packet will be used for setting the hosts IP address.
8920 + * \note This works only if UIP_FIXEDADDR is 0.
8922 + * \hideinitializer
8924 +#define UIP_PINGADDRCONF 0
8926 +#define UIP_IPADDR0 192 /**< The first octet of the IP address of
8927 + this uIP node, if UIP_FIXEDADDR is
8928 + 1. \hideinitializer */
8929 +#define UIP_IPADDR1 168 /**< The second octet of the IP address of
8930 + this uIP node, if UIP_FIXEDADDR is
8931 + 1. \hideinitializer */
8932 +#define UIP_IPADDR2 0 /**< The third octet of the IP address of
8933 + this uIP node, if UIP_FIXEDADDR is
8934 + 1. \hideinitializer */
8935 +#define UIP_IPADDR3 250 /**< The fourth octet of the IP address of
8936 + this uIP node, if UIP_FIXEDADDR is
8937 + 1. \hideinitializer */
8939 +#define UIP_NETMASK0 255 /**< The first octet of the netmask of
8940 + this uIP node, if UIP_FIXEDADDR is
8941 + 1. \hideinitializer */
8942 +#define UIP_NETMASK1 255 /**< The second octet of the netmask of
8943 + this uIP node, if UIP_FIXEDADDR is
8944 + 1. \hideinitializer */
8945 +#define UIP_NETMASK2 255 /**< The third octet of the netmask of
8946 + this uIP node, if UIP_FIXEDADDR is
8947 + 1. \hideinitializer */
8948 +#define UIP_NETMASK3 0 /**< The fourth octet of the netmask of
8949 + this uIP node, if UIP_FIXEDADDR is
8950 + 1. \hideinitializer */
8952 +#define UIP_DRIPADDR0 192 /**< The first octet of the IP address of
8953 + the default router, if UIP_FIXEDADDR is
8954 + 1. \hideinitializer */
8955 +#define UIP_DRIPADDR1 168 /**< The second octet of the IP address of
8956 + the default router, if UIP_FIXEDADDR is
8957 + 1. \hideinitializer */
8958 +#define UIP_DRIPADDR2 0 /**< The third octet of the IP address of
8959 + the default router, if UIP_FIXEDADDR is
8960 + 1. \hideinitializer */
8961 +#define UIP_DRIPADDR3 1 /**< The fourth octet of the IP address of
8962 + the default router, if UIP_FIXEDADDR is
8963 + 1. \hideinitializer */
8966 + * Specifies if the uIP ARP module should be compiled with a fixed
8967 + * Ethernet MAC address or not.
8969 + * If this configuration option is 0, the macro uip_setethaddr() can
8970 + * be used to specify the Ethernet address at run-time.
8972 + * \hideinitializer
8974 +#define UIP_FIXEDETHADDR 0
8976 +#define UIP_ETHADDR0 0x00 /**< The first octet of the Ethernet
8977 + address if UIP_FIXEDETHADDR is
8978 + 1. \hideinitializer */
8979 +#define UIP_ETHADDR1 0xbd /**< The second octet of the Ethernet
8980 + address if UIP_FIXEDETHADDR is
8981 + 1. \hideinitializer */
8982 +#define UIP_ETHADDR2 0x3b /**< The third octet of the Ethernet
8983 + address if UIP_FIXEDETHADDR is
8984 + 1. \hideinitializer */
8985 +#define UIP_ETHADDR3 0x33 /**< The fourth octet of the Ethernet
8986 + address if UIP_FIXEDETHADDR is
8987 + 1. \hideinitializer */
8988 +#define UIP_ETHADDR4 0x05 /**< The fifth octet of the Ethernet
8989 + address if UIP_FIXEDETHADDR is
8990 + 1. \hideinitializer */
8991 +#define UIP_ETHADDR5 0x71 /**< The sixth octet of the Ethernet
8992 + address if UIP_FIXEDETHADDR is
8993 + 1. \hideinitializer */
8996 +/*------------------------------------------------------------------------------*/
8998 + * \defgroup uipoptip IP configuration options
9003 + * The IP TTL (time to live) of IP packets sent by uIP.
9005 + * This should normally not be changed.
9007 +#define UIP_TTL 255
9010 + * Turn on support for IP packet reassembly.
9012 + * uIP supports reassembly of fragmented IP packets. This features
9013 + * requires an additonal amount of RAM to hold the reassembly buffer
9014 + * and the reassembly code size is approximately 700 bytes. The
9015 + * reassembly buffer is of the same size as the uip_buf buffer
9016 + * (configured by UIP_BUFSIZE).
9018 + * \note IP packet reassembly is not heavily tested.
9020 + * \hideinitializer
9022 +#define UIP_REASSEMBLY 0
9025 + * The maximum time an IP fragment should wait in the reassembly
9026 + * buffer before it is dropped.
9029 +#define UIP_REASS_MAXAGE 40
9033 +/*------------------------------------------------------------------------------*/
9035 + * \defgroup uipoptudp UDP configuration options
9038 + * \note The UDP support in uIP is still not entirely complete; there
9039 + * is no support for sending or receiving broadcast or multicast
9040 + * packets, but it works well enough to support a number of vital
9041 + * applications such as DNS queries, though
9045 + * Toggles wether UDP support should be compiled in or not.
9047 + * \hideinitializer
9052 + * Toggles if UDP checksums should be used or not.
9054 + * \note Support for UDP checksums is currently not included in uIP,
9055 + * so this option has no function.
9057 + * \hideinitializer
9059 +#define UIP_UDP_CHECKSUMS 0
9062 + * The maximum amount of concurrent UDP connections.
9064 + * \hideinitializer
9066 +#define UIP_UDP_CONNS 10
9069 + * The name of the function that should be called when UDP datagrams arrive.
9071 + * \hideinitializer
9073 +#define UIP_UDP_APPCALL udp_appcall
9076 +/*------------------------------------------------------------------------------*/
9078 + * \defgroup uipopttcp TCP configuration options
9083 + * Determines if support for opening connections from uIP should be
9086 + * If the applications that are running on top of uIP for this project
9087 + * do not need to open outgoing TCP connections, this configration
9088 + * option can be turned off to reduce the code size of uIP.
9090 + * \hideinitializer
9092 +#define UIP_ACTIVE_OPEN 1
9095 + * The maximum number of simultaneously open TCP connections.
9097 + * Since the TCP connections are statically allocated, turning this
9098 + * configuration knob down results in less RAM used. Each TCP
9099 + * connection requires approximatly 30 bytes of memory.
9101 + * \hideinitializer
9103 +#define UIP_CONNS 10
9106 + * The maximum number of simultaneously listening TCP ports.
9108 + * Each listening TCP port requires 2 bytes of memory.
9110 + * \hideinitializer
9112 +#define UIP_LISTENPORTS 10
9115 + * The size of the advertised receiver's window.
9117 + * Should be set low (i.e., to the size of the uip_buf buffer) is the
9118 + * application is slow to process incoming data, or high (32768 bytes)
9119 + * if the application processes data quickly.
9121 + * \hideinitializer
9123 +#define UIP_RECEIVE_WINDOW 32768
9126 + * Determines if support for TCP urgent data notification should be
9129 + * Urgent data (out-of-band data) is a rarely used TCP feature that
9130 + * very seldom would be required.
9132 + * \hideinitializer
9134 +#define UIP_URGDATA 1
9137 + * The initial retransmission timeout counted in timer pulses.
9139 + * This should not be changed.
9144 + * The maximum number of times a segment should be retransmitted
9145 + * before the connection should be aborted.
9147 + * This should not be changed.
9149 +#define UIP_MAXRTX 8
9152 + * The maximum number of times a SYN segment should be retransmitted
9153 + * before a connection request should be deemed to have been
9156 + * This should not need to be changed.
9158 +#define UIP_MAXSYNRTX 3
9161 + * The TCP maximum segment size.
9163 + * This is should not be to set to more than UIP_BUFSIZE - UIP_LLH_LEN - 40.
9165 +#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - 40)
9168 + * How long a connection should stay in the TIME_WAIT state.
9170 + * This configiration option has no real implication, and it should be
9173 +#define UIP_TIME_WAIT_TIMEOUT 120
9177 +/*------------------------------------------------------------------------------*/
9179 + * \defgroup uipoptarp ARP configuration options
9184 + * The size of the ARP table.
9186 + * This option should be set to a larger value if this uIP node will
9187 + * have many connections from the local network.
9189 + * \hideinitializer
9191 +#define UIP_ARPTAB_SIZE 8
9194 + * The maxium age of ARP table entries measured in 10ths of seconds.
9196 + * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
9199 +#define UIP_ARP_MAXAGE 120
9203 +/*------------------------------------------------------------------------------*/
9206 + * \defgroup uipoptgeneral General configuration options
9211 + * The size of the uIP packet buffer.
9213 + * The uIP packet buffer should not be smaller than 60 bytes, and does
9214 + * not need to be larger than 1500 bytes. Lower size results in lower
9215 + * TCP throughput, larger size results in higher TCP throughput.
9217 + * \hideinitializer
9219 +#define UIP_BUFSIZE 1500
9223 + * Determines if statistics support should be compiled in.
9225 + * The statistics is useful for debugging and to show the user.
9227 + * \hideinitializer
9229 +#define UIP_STATISTICS 1
9232 + * Determines if logging of certain events should be compiled in.
9234 + * This is useful mostly for debugging. The function uip_log()
9235 + * must be implemented to suit the architecture of the project, if
9236 + * logging is turned on.
9238 + * \hideinitializer
9240 +#define UIP_LOGGING 0
9243 + * Print out a uIP log message.
9245 + * This function must be implemented by the module that uses uIP, and
9246 + * is called by uIP whenever a log message is generated.
9248 +void uip_log(char *msg);
9251 + * The link level header length.
9253 + * This is the offset into the uip_buf where the IP header can be
9254 + * found. For Ethernet, this should be set to 14. For SLIP, this
9255 + * should be set to 0.
9257 + * \hideinitializer
9259 +#define UIP_LLH_LEN 14
9263 +/*------------------------------------------------------------------------------*/
9265 + * \defgroup uipoptcpu CPU architecture configuration
9268 + * The CPU architecture configuration is where the endianess of the
9269 + * CPU on which uIP is to be run is specified. Most CPUs today are
9270 + * little endian, and the most notable exception are the Motorolas
9271 + * which are big endian. The BYTE_ORDER macro should be changed to
9272 + * reflect the CPU architecture on which uIP is to be run.
9274 +#ifndef LITTLE_ENDIAN
9275 +#define LITTLE_ENDIAN 3412
9276 +#endif /* LITTLE_ENDIAN */
9278 +#define BIG_ENDIAN 1234
9279 +#endif /* BIGE_ENDIAN */
9282 + * The byte order of the CPU architecture on which uIP is to be run.
9284 + * This option can be either BIG_ENDIAN (Motorola byte order) or
9285 + * LITTLE_ENDIAN (Intel byte order).
9287 + * \hideinitializer
9289 +/*#ifndef BYTE_ORDER*/
9290 +#define BYTE_ORDER BIG_ENDIAN
9291 +/*#endif*/ /* BYTE_ORDER */
9294 +/*------------------------------------------------------------------------------*/
9297 + * \defgroup uipoptapp Appication specific configurations
9300 + * An uIP application is implemented using a single application
9301 + * function that is called by uIP whenever a TCP/IP event occurs. The
9302 + * name of this function must be registered with uIP at compile time
9303 + * using the UIP_APPCALL definition.
9305 + * uIP applications can store the application state within the
9306 + * uip_conn structure by specifying the size of the application
9307 + * structure with the UIP_APPSTATE_SIZE macro.
9309 + * The file containing the definitions must be included in the
9312 + * The following example illustrates how this can look.
9315 +void httpd_appcall(void);
9316 +#define UIP_APPCALL httpd_appcall
9318 +struct httpd_state {
9324 +#define UIP_APPSTATE_SIZE (sizeof(struct httpd_state))
9329 + * \var #define UIP_APPCALL
9331 + * The name of the application function that uIP should call in
9332 + * response to TCP/IP events.
9337 + * \var #define UIP_APPSTATE_SIZE
9339 + * The size of the application state that is to be stored in the
9340 + * uip_conn structure.
9344 +/* Include the header file for the application program that should be
9345 + used. If you don't use the example web server, you should change
9350 +#endif /* __UIPOPT_H__ */