diff --git a/Makefile b/Makefile deleted file mode 100644 index a5c886dc..00000000 --- a/Makefile +++ /dev/null @@ -1,108 +0,0 @@ -TOPDIR = $(shell pwd) -ARCH = x86 -NAME = metalsvm -LWIPDIRS = lwip/src/api lwip/src/core lwip/src/core/ipv4 lwip/src/netif -DRIVERDIRS = drivers/net drivers/char -KERNDIRS = libkern kernel mm fs arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/scc $(LWIPDIRS) $(DRIVERDIRS) -SUBDIRS = $(KERNDIRS) - -CC_FOR_TARGET=i386-unknown-linux-gnu-gcc -CXX_FOR_TARGET=i386-unknown-linux-gnu-g++ -GCC_FOR_TARGET=i386-unknown-linux-gnu-gcc -AR_FOR_TARGET=i386-unknown-linux-gnu-ar -AS_FOR_TARGET=i386-unknown-linux-gnu-as -LD_FOR_TARGET=i386-unknown-linux-gnu-ld -NM_FOR_TARGET=i386-unknown-linux-gnu-nm -OBJDUMP_FOR_TARGET=i386-unknown-linux-gnu-objdump -OBJCOPY_FOR_TARGET=i386-unknown-linux-gnu-objcopy -RANLIB_FOR_TARGET=i386-unknown-linux-gnu-ranlib -STRIP_FOR_TARGET=i386-unknown-linux-gnu-strip -READELF_FOR_TARGET=i386-unknown-linux-gnu-readelf -NASM = nasm -EMU=qemu -GDB=gdb - -MAKE = make -NASMFLAGS = -felf32 -g -INCLUDE = -I$(TOPDIR)/include -I$(TOPDIR)/arch/$(ARCH)/include -I$(TOPDIR)/lwip/src/include -I$(TOPDIR)/lwip/src/include/ipv4 -I$(TOPDIR)/drivers -# Compiler options for final code -CFLAGS = -g -m32 -march=i586 -Wall -O2 -fno-zero-initialized-in-bss -fno-builtin -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc $(INCLUDE) -# Compiler options for debuuging -#CFLAGS = -g -O -m32 -march=i586 -Wall -fno-zero-initialized-in-bss -fno-builtin -DWITH_FRAME_POINTER -nostdinc $(INCLUDE) -ARFLAGS = rsv -RM = rm -rf -LDFLAGS = -T link.ld -z max-page-size=4096 --defsym __BUILD_DATE=$(shell date +'%Y%m%d') --defsym __BUILD_TIME=$(shell date +'%H%M%S') -STRIP_DEBUG = --strip-debug -KEEP_DEBUG = --only-keep-debug - -# Prettify output -V = 0 -ifeq ($V,0) - Q = @ - P = > /dev/null -endif - -default: all - -all: newlib tools $(NAME).elf - -newlib: - $(MAKE) ARCH=$(ARCH) LDFLAGS="-m32" CFLAGS="-m32 -O2 -march=i586 " NASMFLAGS="$(NASMFLAGS)" CC_FOR_TARGET=$(CC_FOR_TARGET) \ - CXX_FOR_TARGET=$(CXX_FOR_TARGET) \ - GCC_FOR_TARGET=$(GCC_FOR_TARGET) \ - AR_FOR_TARGET=$(AR_FOR_TARGET) \ - AS_FOR_TARGET=$(AS_FOR_TARGET) \ - LD_FOR_TARGET=$(LD_FOR_TARGET) \ - NM_FOR_TARGET=$(NM_FOR_TARGET) \ - OBJDUMP_FOR_TARGET=$(OBJDUMP_FOR_TARGET) \ - OBJCOPY_FOR_TARGET=$(OBJCOPY_FOR_TARGET) \ - RANLIB_FOR_TARGET=$(RANLIB_FOR_TARGET) \ - STRIP_FOR_TARGET=$(STRIP_FOR_TARGET) \ - READELF_FOR_TARGET=$(READELF_FOR_TARGET) -C newlib - -tools: - $(MAKE) -C tools - -$(NAME).elf: - $Q$(LD_FOR_TARGET) $(LDFLAGS) -o $(NAME).elf $^ - @echo [OBJCOPY] $(NAME).sym - $Q$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $(NAME).elf $(NAME).sym - @echo [OBJCOPY] $(NAME).elf - $Q$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $(NAME).elf - -qemu: newlib tools $(NAME).elf - qemu -smp 2 -net nic,model=rtl8139 -net user,hostfwd=tcp::12345-:7 -net dump -kernel metalsvm.elf -initrd tools/initrd.img - -qemudbg: newlib tools $(NAME).elf - qemu -S -s -smp 2 -net nic,model=rtl8139 -net user,hostfwd=tcp::12345-:7 -net dump -kernel metalsvm.elf -initrd tools/initrd.img - -gdb: $(NAME).elf - make qemudbg > /dev/null & - $(GDB) -x script.gdb - -clean: - $Q$(RM) $(NAME).elf $(NAME).sym *~ - $Q$(MAKE) -C tools clean - @echo Cleaned. - -veryclean: clean - $Q$(MAKE) -C newlib veryclean - @echo Very cleaned - -#depend: -# for i in $(SUBDIRS); do $(MAKE) -k -C $$i depend; done - -%.o : %.c - @echo [CC] $@ - $Q$(CC_FOR_TARGET) -c -D__KERNEL__ $(CFLAGS) -o $@ $< - @echo [DEP] $*.dep - $Q$(CC_FOR_TARGET) -MF $*.dep -MT $*.o -MM $(CFLAGS) $< - - -%.o : %.asm - @echo [ASM] $@ - $Q$(NASM) $(NASMFLAGS) -o $@ $< - -.PHONY: default all clean emu gdb newlib tools - -include $(addsuffix /Makefile,$(SUBDIRS)) diff --git a/arch/x86/include/asm/SCC_API.h b/arch/x86/include/asm/SCC_API.h index eb1bf99c..8812fefc 100644 --- a/arch/x86/include/asm/SCC_API.h +++ b/arch/x86/include/asm/SCC_API.h @@ -155,6 +155,9 @@ #define CRB_X5_Y3 0xf7000000 #define CRB_OWN 0xf8000000 +// FPGA registers +#define FPGA_BASE 0xf9000000 + // Symbol for RPC #define RPC_BASE 0xfb000000 diff --git a/arch/x86/include/asm/tasks_types.h b/arch/x86/include/asm/tasks_types.h index ffaee4fd..34c01228 100644 --- a/arch/x86/include/asm/tasks_types.h +++ b/arch/x86/include/asm/tasks_types.h @@ -68,6 +68,13 @@ static inline void save_fpu_state(union fpu_state* state) { asm volatile ("fsave %0; fwait" : "=m"((*state).fsave)); } +static inline void restore_fpu_state(union fpu_state* state) { + if (has_fxsr()) + asm volatile ("fxrstor %0" :: "m"(state->fxsave)); + else + asm volatile ("frstor %0" :: "m"(state->fsave)); +} + #ifdef __cplusplus } #endif diff --git a/arch/x86/kernel/entry.asm b/arch/x86/kernel/entry.asm index 5610c6b8..6fb00652 100644 --- a/arch/x86/kernel/entry.asm +++ b/arch/x86/kernel/entry.asm @@ -73,7 +73,7 @@ stublet: ; clears the current pgd entry xor eax, eax mov cr3, eax -; disable SSE support (TODO) +; at this stage, we disable the SSE support mov eax, cr4 and eax, 0xfffbf9ff mov cr4, eax diff --git a/arch/x86/kernel/gdt.c b/arch/x86/kernel/gdt.c index 5be409c6..ed863eaa 100644 --- a/arch/x86/kernel/gdt.c +++ b/arch/x86/kernel/gdt.c @@ -28,10 +28,10 @@ gdt_ptr_t gp; static tss_t task_state_segments[MAX_TASKS] __attribute__ ((aligned (PAGE_SIZE))); -static unsigned char kstacks[MAX_TASKS][KERNEL_STACK_SIZE] __attribute__ ((aligned (PAGE_SIZE))); +static unsigned char kstacks[MAX_TASKS][KERNEL_STACK_SIZE] __attribute__ ((aligned (PAGE_SIZE), section (".data"))); // currently, our kernel has full access to the ioports static gdt_entry_t gdt[GDT_ENTRIES] = {[0 ... GDT_ENTRIES-1] = {0, 0, 0, 0, 0, 0}}; -unsigned char* default_stack_pointer = kstacks[0] + KERNEL_STACK_SIZE - sizeof(size_t); +unsigned char* default_stack_pointer __attribute__ ((section (".data"))) = kstacks[0] + KERNEL_STACK_SIZE - sizeof(size_t); /* * This is in start.asm. We use this to properly reload diff --git a/arch/x86/kernel/isrs.c b/arch/x86/kernel/isrs.c index 4c461894..ed0d6792 100644 --- a/arch/x86/kernel/isrs.c +++ b/arch/x86/kernel/isrs.c @@ -196,11 +196,7 @@ static void fpu_handler(struct state *s) task->flags |= TASK_FPU_INIT; } - // restore the FPU context - if (has_fxsr()) - asm volatile ("fxrstor %0" :: "m"(task->fpu.fxsave)); - else - asm volatile ("frstor %0" :: "m"(task->fpu.fsave)); + restore_fpu_state(&task->fpu); task->flags |= TASK_FPU_USED; } diff --git a/arch/x86/kernel/multiboot.c b/arch/x86/kernel/multiboot.c index d57b5f96..ec124479 100644 --- a/arch/x86/kernel/multiboot.c +++ b/arch/x86/kernel/multiboot.c @@ -37,7 +37,7 @@ */ /** Global multiboot information structure pointer */ -multiboot_info_t* mb_info = NULL; +multiboot_info_t* mb_info __attribute__ ((section (".data"))) = NULL; #endif /** @brief initialization procedure for Multiboot information structure diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index 184f8865..4551edc1 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -733,6 +733,10 @@ int arch_paging_init(void) // map SCC's message passing buffers viraddr = map_region(MPB_X0_Y0, MPB_X0_Y0, (MPB_OWN-MPB_X0_Y0+16*1024*1024) >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_MPE); kprintf("Map message passing buffers at 0x%x\n", viraddr); + + // map the FPGA registers + viraddr = map_region(FPGA_BASE, FPGA_BASE, 0x10000 >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_NO_CACHE); + kprintf("Map FPGA regsiters at 0x%x\n", viraddr); #endif /* enable paging */ diff --git a/arch/x86/scc/RCCE_admin.c b/arch/x86/scc/RCCE_admin.c index a9a624ae..2ad87e18 100644 --- a/arch/x86/scc/RCCE_admin.c +++ b/arch/x86/scc/RCCE_admin.c @@ -337,7 +337,7 @@ int RCCE_init( RCCE_shmalloc_init(RC_SHM_BUFFER_START()+RCCE_SHM_BUFFER_offset ,RCCE_SHM_SIZE_MAX); #ifdef SHMDBG - kprintf("\n%d:%s:%d: RCCE_SHM_BUFFER_offset, RCCE_SHM_SIZE_MAX: % x %x\n", RCCE_IAM, + kprintf("\n%d:%s:%d: RCCE_SHM_BUFFER_offset, RCCE_SHM_SIZE_MAX: %x %x\n", RCCE_IAM, __FILE__,__LINE__,RCCE_SHM_BUFFER_offset ,RCCE_SHM_SIZE_MAX); #endif #else diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 05292396..730add0b 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -132,6 +132,7 @@ int icc_init(void) RCCE_barrier(&RCCE_COMM_WORLD); +#if 0 kputs("RCCE test...\t"); if (my_ue == 0) msg = 0x4711; @@ -139,6 +140,7 @@ int icc_init(void) kprintf("successfull! (0x%x)\n", msg); else kprintf("failed! (0x%x)\n", msg); +#endif // reset INTR/LINT0 flag z = Z_PID(RC_COREID[my_ue]); @@ -147,7 +149,7 @@ int icc_init(void) SetConfigReg(CRB_OWN + (z==0 ? GLCFG0 : GLCFG1), tmp); // set interrupt handler (INTR/LINT0) - irq_install_handler(124, intr_handler); + //irq_install_handler(124, intr_handler); kputs("Now, the SCC is initialized!\n"); diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 1f966ff1..a52d53fa 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -1,4 +1,4 @@ -C_source := rtl8139.c mmnif.c +C_source := rtl8139.c rckemac.c mmnif.c MODULE := drivers_net include $(TOPDIR)/Makefile.inc diff --git a/kernel/init.c b/kernel/init.c index 791cdc0f..17b31c37 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -37,7 +37,11 @@ #include #endif #include -#include +#include +#ifdef CONFIG_ROCKCREEK +#include +#include +#endif void echo_init(void); void ping_init(void); @@ -58,11 +62,12 @@ int lowlevel_init(void) koutput_init(); + //kprintf("Now, the BSS section (0x%x - 0x%x) is initialized.\n", (size_t) &bss_start, (size_t) &bss_end); + return 0; } - -#if defined(CONFIG_LWIP) && defined(CONFIG_PCI) +#if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK)) static tid_t netid; int STDCALL network_task(void* arg) @@ -74,10 +79,15 @@ int STDCALL network_task(void* arg) kputs("Network task is started\n"); +#ifdef CONFIG_ROCKCREEK /* Set network address variables */ - //IP4_ADDR(&gw, 192,168,1,254); - //IP4_ADDR(&ipaddr, 192,168,1,100); - //IP4_ADDR(&netmask, 255,255,255,0); + IP4_ADDR(&gw, 192,168,4,254); + IP4_ADDR(&ipaddr, 192,168,4,RCCE_ue()+1); + IP4_ADDR(&netmask, 255,255,255,0); + + /* Bring up the network interface */ + if (!netif_add(&netif, &ipaddr, &netmask, &gw, NULL, rckemacif_init, ethernet_input)) { +#else /* Clear network address because we use DHCP to get an ip address */ IP4_ADDR(&gw, 0,0,0,0); IP4_ADDR(&ipaddr, 0,0,0,0); @@ -85,17 +95,15 @@ int STDCALL network_task(void* arg) /* Bring up the network interface */ if (!netif_add(&netif, &ipaddr, &netmask, &gw, NULL, rtl8139if_init, ethernet_input)) { +#endif kputs("Unable to add network interface\n"); return -ENXIO; } netif_set_default(&netif); + netif_set_up(&netif); - if (netif_is_up(&netif)) { - kputs("Network interface is not up\n"); - return -EIO; - } - +#ifndef CONFIG_ROCKCREEK kprintf("Starting DHCPCD...\n"); dhcp_start(&netif); @@ -104,17 +112,24 @@ int STDCALL network_task(void* arg) rtl8139if_wait(&netif, 1); udelay(500000); } +#endif // start echo and ping server echo_init(); - ping_init(); + //ping_init(); while(!done) { +#ifdef CONFIG_PCI rtl8139if_wait(&netif, 0); +#elif defined(CONFIG_ROCKCREEK) + rckemacif_wait(&netif, 0); +#endif } +#ifndef CONFIG_ROCKCREEK dhcp_release(&netif); dhcp_stop(&netif); +#endif return 0; } @@ -127,28 +142,16 @@ int network_shutdown(void) return 0; } -void tcp_init_ok(void* e) -{ - kprintf("TCP/IP init COMPLETE!!!!!!"); -} - int network_init(void) { - tcpip_init(tcp_init_ok,NULL); - kprintf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); - mmnif_open(); - kprintf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); - return 0; -#if 0 #if defined(CONFIG_LWIP) // Initialize lwIP modules lwip_init(); #endif -#if defined(CONFIG_LWIP) && defined(CONFIG_PCI) +#if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK)) return create_kernel_task(&netid, network_task, NULL); #else return 0; #endif -#endif } diff --git a/kernel/main.c b/kernel/main.c index 75fffb0c..daf7f3af 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -112,8 +112,8 @@ int main(void) kprintf("Current allocated memory: %u KBytes\n", atomic_int32_read(&total_allocated_pages)*(PAGE_SIZE/1024)); kprintf("Current available memory: %u MBytes\n", atomic_int32_read(&total_available_pages)/((1024*1024)/PAGE_SIZE)); -// sleep(5); -// list_root(); + sleep(5); + list_root(); test_init(); per_core(current_task)->status = TASK_IDLE; diff --git a/kernel/ping.c b/kernel/ping.c index 5c84586f..98398300 100644 --- a/kernel/ping.c +++ b/kernel/ping.c @@ -38,9 +38,6 @@ * */ -//#define PING_USE_SOCKETS 1 - - #include #include #include @@ -56,6 +53,10 @@ #include #include +#if LWIP_SOCKET +#define PING_USE_SOCKETS 1 +#endif + #if PING_USE_SOCKETS #include #include @@ -71,7 +72,7 @@ /** ping target - should be a "ip_addr_t" */ #ifndef PING_TARGET -#define PING_TARGET (netif_default?netif_default->gw:ip_addr_any) +#define PING_TARGET (netif_default?netif_default->gw:ip_addr_any) #endif /** ping receive timeout - in milliseconds */ diff --git a/kernel/tests.c b/kernel/tests.c index a6789994..1fbc7a48 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -26,14 +26,6 @@ #include #ifdef CONFIG_ROCKCREEK #include -#include -#include -#include -#include -#include - -#include -#include #endif static sem_t consuming, producing; @@ -127,166 +119,23 @@ static int STDCALL join_test(void* arg) void ping_send_now(); -__inline int get_core_no(void) -{ - unsigned int tmp; - unsigned int pid; - unsigned int x,y,z; - /* Determine the local IP address from the core number in the - * tile ID register - */ - tmp = ReadConfigReg(0xF8000000 + 0x100); - x = (tmp>>3) & 0x0f; /* bits 06:03 */ - y = (tmp>>7) & 0x0f; /* bits 10:07 */ - z = (tmp ) & 0x07; /* bits 02:00 */ - pid = 12*y + 2*x + z; - /* Add 1 to the processor ID to avoid *.*.*.0 IP addresses */ - return pid; -} - -void* server_task(void* e) -{ - int sockfd, newsockfd, portno, clilen; - char buffer[256]; - struct sockaddr_in serv_addr, cli_addr; - int n; - - /* First call to socket() function */ - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd < 0) - { - kprintf("ERROR opening socket"); - return; - } - /* Initialize socket structure */ - memset((char *) &serv_addr,0, sizeof(serv_addr)); - portno = 5001; - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = INADDR_ANY; - serv_addr.sin_port = htons(portno); - - kprintf("binding"); - /* Now bind the host address using bind() call.*/ - if (bind(sockfd, (struct sockaddr *) &serv_addr, - sizeof(serv_addr)) < 0) - { - kprintf("ERROR on binding"); - return; - } - - /* Now start listening for the clients, here process will - * go in sleep mode and will wait for the incoming connection - */ - kprintf("listening"); - listen(sockfd,5); - clilen = sizeof(cli_addr); - - /* Accept actual connection from the client */ - kprintf("accepting"); - newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, - &clilen); - if (newsockfd < 0) - { - kprintf("ERROR on accept"); - return; - } - /* If connection is established then start communicating */ - memset(buffer,0,256); - kprintf("recieving"); - n = read( newsockfd,buffer,255 ); - if (n < 0) - { - kprintf("ERROR reading from socket"); - return; - } - kprintf("Here is the message: %s\n",buffer); - - /* Write a response to the client */ - kprintf("writing"); - n = write(newsockfd,"I got your message",18); - if (n < 0) - { - kprintf("ERROR writing to socket"); - return; - } - return 0; -} - -void* client_task(void* e) -{ - char dir[256]; - int sd; - struct sockaddr_in sin; - struct sockaddr_in pin; - struct hostent *hp; - - - /* fill in the socket structure with host information */ - memset(&pin, 0, sizeof(pin)); - pin.sin_family = AF_INET; - pin.sin_addr.s_addr = inet_addr("192.168.0.1"); - pin.sin_port = htons(5001); - - /* grab an Internet domain socket */ - if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - kprintf("socketfail"); - return; - } - - kprintf("connecting"); - /* connect to PORT on HOST */ - if (connect(sd,(struct sockaddr *) &pin, sizeof(pin)) == -1) { - kprintf("connectfail"); - return; - } - kprintf("sending"); - /* send a message to the server PORT on machine HOST */ - if (send(sd, "HELLO THERE", strlen("HELLO THERE"), 0) == -1) { - kprintf("sendfail"); - return; - } - kprintf("recieving"); - /* wait for a message to come back from the server */ - if (recv(sd, dir, 256, 0) == -1) { - kprintf("recvfail"); - return; - } - - /* spew-out the results and bail out of here! */ - kprintf("%s\n", dir); - - close(sd); - -return NULL; -} - int test_init(void) { - if (!get_core_no()) - create_kernel_task(NULL,server_task,NULL); - else - create_kernel_task(NULL,client_task,NULL); + char* argv[] = {"/bin/tests", NULL}; -// char* argv[] = {"/bin/tests", NULL}; + sem_init(&producing, 1); + sem_init(&consuming, 0); + mailbox_int32_init(&mbox); -// sem_init(&producing, 1); -// sem_init(&consuming, 0); -// mailbox_int32_init(&mbox); - -// create_kernel_task(NULL, foo, "Hello from foo1\n"); + create_kernel_task(NULL, foo, "Hello from foo1\n"); //create_kernel_task(NULL, join_test, NULL); //create_kernel_task(NULL, producer, NULL); //create_kernel_task(NULL, consumer, NULL); //create_kernel_task(NULL, ping, NULL); //create_user_task(NULL, "/bin/hello", argv); -// create_user_task(NULL, "/bin/tests", argv); + create_user_task(NULL, "/bin/tests", argv); //create_user_task(NULL, "/bin/jacobi", argv); //create_user_task(NULL, "/bin/jacobi", argv); -#ifdef CONFIG_LWIP - // use ping to test LWIP -// ping_send_now(); -#endif - return 0; } diff --git a/lwip/CHANGELOG b/lwip/CHANGELOG index aaea2727..6e27a66b 100644 --- a/lwip/CHANGELOG +++ b/lwip/CHANGELOG @@ -1,18 +1,25 @@ -FUTURE - - * TODO: The lwIP source code makes some invalid assumptions on processor - word-length, storage sizes and alignment. See the mailing lists for - problems with exoteric (/DSP) architectures showing these problems. - We still have to fix some of these issues neatly. - HISTORY (CVS HEAD) * [Enter new changes just after this line - do not remove this line] + ++ New features: + + + ++ Bugfixes: + + + + +(STABLE-1.4.0) + ++ New features: + 2011-03-27: Simon Goldschmidt + * tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and + calculate it in tcp_zero_window_probe (the only place where it was used). + 2010-11-21: Simon Goldschmidt * dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif (fixes bug #31525). @@ -233,6 +240,62 @@ HISTORY ++ Bugfixes: + 2011-04-20: Simon Goldschmidt + * sys_arch.txt: sys_arch_timeouts() is not needed any more. + + 2011-04-13: Simon Goldschmidt + * tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by + using ports in the IANA private/dynamic range (49152 through 65535). + + 2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl: + * etharp.h/.c: Fixed broken VLAN support. + + 2011-03-27: Simon Goldschmidt + * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp + pcbs) by checking if the pcb was bound (local_port != 0). + + 2011-03-27: Simon Goldschmidt + * ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice) + + 2011-03-27: Simon Goldschmidt + * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and + raw pcbs with LWIP_TCPIP_CORE_LOCKING==1. + + 2011-03-27: Simon Goldschmidt + * tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route + is present never times out) by starting retransmission timer before checking + route. + + 2011-03-22: Simon Goldschmidt + * ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only + calling sio_read_abort() if the file descriptor is valid. + + 2011-03-14: Simon Goldschmidt + * err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect + more than once can render a socket useless) since it mainly involves changing + "FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal. + + 2011-03-13: Simon Goldschmidt + * sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing + err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN: + use EALRADY instead of -1 + + 2011-03-13: Simon Goldschmidt + * api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the + connection has been aborted by err_tcp (since this is not a normal closing + procedure). + + 2011-03-13: Simon Goldschmidt + * tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind + with pcb->state != CLOSED + + 2011-02-17: Simon Goldschmidt + * rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in + documentation + + 2011-02-17: Simon Goldschmidt + * many files: Added missing U/UL modifiers to fix 16-bit-arch portability. + 2011-01-24: Simon Goldschmidt * sockets.c: Fixed bug #31741: lwip_select seems to have threading problems diff --git a/lwip/doc/rawapi.txt b/lwip/doc/rawapi.txt index 65f82bc5..bd452cf9 100644 --- a/lwip/doc/rawapi.txt +++ b/lwip/doc/rawapi.txt @@ -251,8 +251,9 @@ if a call to tcp_write() has failed because memory wasn't available, the application may use the polling functionality to call tcp_write() again when the connection has been idle for a while. -- void tcp_poll(struct tcp_pcb *pcb, u8_t interval, - err_t (* poll)(void *arg, struct tcp_pcb *tpcb)) +- void tcp_poll(struct tcp_pcb *pcb, + err_t (* poll)(void *arg, struct tcp_pcb *tpcb), + u8_t interval) Specifies the polling interval and the callback function that should be called to poll the application. The interval is specified in diff --git a/lwip/doc/sys_arch.txt b/lwip/doc/sys_arch.txt index 66310a91..38377b66 100644 --- a/lwip/doc/sys_arch.txt +++ b/lwip/doc/sys_arch.txt @@ -123,18 +123,6 @@ The following functions must be implemented by the sys_arch: sys_arch_mbox_fetch(mbox,msg,1) although this would introduce unnecessary delays. -- struct sys_timeouts *sys_arch_timeouts(void) - - Returns a pointer to the per-thread sys_timeouts structure. In lwIP, - each thread has a list of timeouts which is repressented as a linked - list of sys_timeout structures. The sys_timeouts structure holds a - pointer to a linked list of timeouts. This function is called by - the lwIP timeout scheduler and must not return a NULL value. - - In a single thread sys_arch implementation, this function will - simply return a pointer to a global sys_timeouts variable stored in - the sys_arch module. - If threads are supported by the underlying operating system and if such functionality is needed in lwIP, the following function will have to be implemented as well: diff --git a/lwip/src/api/Makefile b/lwip/src/api/Makefile index 282dab02..01a9faf4 100644 --- a/lwip/src/api/Makefile +++ b/lwip/src/api/Makefile @@ -1,4 +1,4 @@ -C_source := err.c sockets.c netbuf.c api_lib.c api_msg.c netdb.c netifapi.c tcpip.c +C_source := api_lib.c api_msg.c err.c netbuf.c netifapi.c sockets.c tcpip.c MODULE := lwip_src_api include $(TOPDIR)/Makefile.inc diff --git a/lwip/src/api/api_lib.c b/lwip/src/api/api_lib.c index 158325b0..b1a9e525 100644 --- a/lwip/src/api/api_lib.c +++ b/lwip/src/api/api_lib.c @@ -307,9 +307,9 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn) API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); if (newconn == NULL) { - /* connection has been closed */ - NETCONN_SET_SAFE_ERR(conn, ERR_CLSD); - return ERR_CLSD; + /* connection has been aborted */ + NETCONN_SET_SAFE_ERR(conn, ERR_ABRT); + return ERR_ABRT; } #if TCP_LISTEN_BACKLOG /* Let the stack know that we have accepted the connection. */ diff --git a/lwip/src/api/api_msg.c b/lwip/src/api/api_msg.c index dcb07e9c..448f96dd 100644 --- a/lwip/src/api/api_msg.c +++ b/lwip/src/api/api_msg.c @@ -950,12 +950,7 @@ do_connected(void *arg, struct tcp_pcb *pcb, err_t err) conn->current_msg = NULL; conn->state = NETCONN_NONE; if (!was_blocking) { - SYS_ARCH_DECL_PROTECT(lev); - SYS_ARCH_PROTECT(lev); - if (conn->last_err == ERR_INPROGRESS) { - conn->last_err = ERR_OK; - } - SYS_ARCH_UNPROTECT(lev); + NETCONN_SET_SAFE_ERR(conn, ERR_OK); } API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); diff --git a/lwip/src/api/err.c b/lwip/src/api/err.c index b0a4eb3e..92fa8b7d 100644 --- a/lwip/src/api/err.c +++ b/lwip/src/api/err.c @@ -49,14 +49,14 @@ static const char *err_strerr[] = { "Operation in progress.", /* ERR_INPROGRESS -5 */ "Illegal value.", /* ERR_VAL -6 */ "Operation would block.", /* ERR_WOULDBLOCK -7 */ - "Connection aborted.", /* ERR_ABRT -8 */ - "Connection reset.", /* ERR_RST -9 */ - "Connection closed.", /* ERR_CLSD -10 */ - "Not connected.", /* ERR_CONN -11 */ - "Illegal argument.", /* ERR_ARG -12 */ - "Address in use.", /* ERR_USE -13 */ - "Low-level netif error.", /* ERR_IF -14 */ - "Already connected.", /* ERR_ISCONN -15 */ + "Address in use.", /* ERR_USE -8 */ + "Already connected.", /* ERR_ISCONN -9 */ + "Connection aborted.", /* ERR_ABRT -10 */ + "Connection reset.", /* ERR_RST -11 */ + "Connection closed.", /* ERR_CLSD -12 */ + "Not connected.", /* ERR_CONN -13 */ + "Illegal argument.", /* ERR_ARG -14 */ + "Low-level netif error.", /* ERR_IF -15 */ }; /** diff --git a/lwip/src/api/sockets.c b/lwip/src/api/sockets.c index f3afd630..e36012ce 100644 --- a/lwip/src/api/sockets.c +++ b/lwip/src/api/sockets.c @@ -141,14 +141,14 @@ static const int err_to_errno_table[] = { EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ EINVAL, /* ERR_VAL -6 Illegal value. */ EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ - ECONNABORTED, /* ERR_ABRT -8 Connection aborted. */ - ECONNRESET, /* ERR_RST -9 Connection reset. */ - ESHUTDOWN, /* ERR_CLSD -10 Connection closed. */ - ENOTCONN, /* ERR_CONN -11 Not connected. */ - EIO, /* ERR_ARG -12 Illegal argument. */ - EADDRINUSE, /* ERR_USE -13 Address in use. */ - -1, /* ERR_IF -14 Low-level netif error */ - -1, /* ERR_ISCONN -15 Already connected. */ + EADDRINUSE, /* ERR_USE -8 Address in use. */ + EALREADY, /* ERR_ISCONN -9 Already connected. */ + ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */ + ECONNRESET, /* ERR_RST -11 Connection reset. */ + ENOTCONN, /* ERR_CLSD -12 Connection closed. */ + ENOTCONN, /* ERR_CONN -13 Not connected. */ + EIO, /* ERR_ARG -14 Illegal argument. */ + -1, /* ERR_IF -15 Low-level netif error */ }; #define ERR_TO_ERRNO_TABLE_SIZE \ @@ -847,8 +847,12 @@ lwip_sendto(int s, const void *data, size_t size, int flags, inet_addr_to_ipaddr_p(remote_addr, &to_in->sin_addr); remote_port = ntohs(to_in->sin_port); } else { - remote_addr = IP_ADDR_ANY; - remote_port = 0; + remote_addr = &sock->conn->pcb.raw->remote_ip; + if (sock->conn->type == NETCONN_RAW) { + remote_port = 0; + } else { + remote_port = sock->conn->pcb.udp->remote_port; + } } LOCK_TCPIP_CORE(); @@ -890,7 +894,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags, netbuf_fromport(&buf) = 0; } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%d"U16_F", flags=0x%x to=", + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=", s, data, short_size, flags)); ip_addr_debug_print(SOCKETS_DEBUG, &buf.addr); LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); diff --git a/lwip/src/api/tcpip.c b/lwip/src/api/tcpip.c index 72019e70..857e7d9b 100644 --- a/lwip/src/api/tcpip.c +++ b/lwip/src/api/tcpip.c @@ -137,7 +137,7 @@ tcpip_thread(void *arg) #endif /* LWIP_TCPIP_TIMEOUT */ default: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", (const char*)msg->type)); + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type)); LWIP_ASSERT("tcpip_thread: invalid message", 0); break; } diff --git a/lwip/src/core/Makefile b/lwip/src/core/Makefile index 640cf829..fc6fd0a9 100644 --- a/lwip/src/core/Makefile +++ b/lwip/src/core/Makefile @@ -1,4 +1,4 @@ -C_source := dhcp.c raw.c init.c mem.c memp.c netif.c pbuf.c stats.c udp.c tcp.c tcp_in.c tcp_out.c sys.c def.c timers.c +C_source := dhcp.c raw.c init.c mem.c memp.c netif.c pbuf.c stats.c udp.c tcp.c tcp_in.c tcp_out.c def.c timers.c MODULE := lwip_src_core include $(TOPDIR)/Makefile.inc diff --git a/lwip/src/core/dhcp.c b/lwip/src/core/dhcp.c index e2f231fc..81b4be27 100644 --- a/lwip/src/core/dhcp.c +++ b/lwip/src/core/dhcp.c @@ -965,11 +965,11 @@ dhcp_bind(struct netif *netif) /* subnet mask not given, choose a safe subnet mask given the network class */ u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr); if (first_octet <= 127) { - ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000)); + ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL)); } else if (first_octet >= 192) { - ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00)); + ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL)); } else { - ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000)); + ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL)); } } @@ -979,7 +979,7 @@ dhcp_bind(struct netif *netif) /* copy network address */ ip_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask); /* use first host address on network as gateway */ - ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001)); + ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL)); } #if LWIP_DHCP_AUTOIP_COOP diff --git a/lwip/src/core/ipv4/icmp.c b/lwip/src/core/ipv4/icmp.c index 02e498d7..32902a52 100644 --- a/lwip/src/core/ipv4/icmp.c +++ b/lwip/src/core/ipv4/icmp.c @@ -191,7 +191,7 @@ icmp_input(struct pbuf *p, struct netif *inp) ip_addr_copy(iphdr->dest, *ip_current_src_addr()); ICMPH_TYPE_SET(iecho, ICMP_ER); /* adjust the checksum */ - if (iecho->chksum >= PP_HTONS(0xffff - (ICMP_ECHO << 8))) { + if (iecho->chksum >= PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1; } else { iecho->chksum += PP_HTONS(ICMP_ECHO << 8); diff --git a/lwip/src/core/ipv4/igmp.c b/lwip/src/core/ipv4/igmp.c index 390a5a74..4e4405e1 100644 --- a/lwip/src/core/ipv4/igmp.c +++ b/lwip/src/core/ipv4/igmp.c @@ -100,7 +100,7 @@ Steve Reynolds */ #define IGMP_TTL 1 #define IGMP_MINLEN 8 -#define ROUTER_ALERT 0x9404 +#define ROUTER_ALERT 0x9404U #define ROUTER_ALERTLEN 4 /* diff --git a/lwip/src/core/ipv4/ip.c b/lwip/src/core/ipv4/ip.c index b5afb5a0..6f248716 100644 --- a/lwip/src/core/ipv4/ip.c +++ b/lwip/src/core/ipv4/ip.c @@ -201,7 +201,7 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) } /* Incrementally update the IP checksum. */ - if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffff - 0x100)) { + if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) { IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1); } else { IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100)); diff --git a/lwip/src/core/ipv4/ip_addr.c b/lwip/src/core/ipv4/ip_addr.c index 7e953d37..8f633ff2 100644 --- a/lwip/src/core/ipv4/ip_addr.c +++ b/lwip/src/core/ipv4/ip_addr.c @@ -93,7 +93,7 @@ ip4_addr_netmask_valid(u32_t netmask) u32_t nm_hostorder = lwip_htonl(netmask); /* first, check for the first zero */ - for (mask = 1U << 31 ; mask != 0; mask >>= 1) { + for (mask = 1UL << 31 ; mask != 0; mask >>= 1) { if ((nm_hostorder & mask) == 0) { break; } diff --git a/lwip/src/core/ipv6/ip6.c b/lwip/src/core/ipv6/ip6.c index 7e434200..b945fc5d 100644 --- a/lwip/src/core/ipv6/ip6.c +++ b/lwip/src/core/ipv6/ip6.c @@ -48,7 +48,7 @@ #include "lwip/netif.h" #include "lwip/icmp.h" #include "lwip/udp.h" -#include "lwip/tcp.h" +#include "lwip/tcp_impl.h" #include "lwip/stats.h" diff --git a/lwip/src/core/sys.c b/lwip/src/core/sys.c index d82a291e..d3a77deb 100644 --- a/lwip/src/core/sys.c +++ b/lwip/src/core/sys.c @@ -1,304 +1,66 @@ -/** - * @file - * lwIP Operating System abstraction - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#include "lwip/sys.h" - -/* Most of the functions defined in sys.h must be implemented in the - * architecture-dependent file sys_arch.c */ - - -#ifdef WIN32 - -#include -#include - -#else - -#include -#include - -#define TRUE 1 -#define FALSE 0 - -#endif -/* sys_now(): retrives tick count to mesure system time - * - */ -u32_t sys_now(void) -{ -#ifdef WIN32 - return GetTickCount(); -#else - return get_clock_tick(); -#endif -} - -#if !NO_SYS - -/** - * Sleep for some ms. Timeouts are NOT processed while sleeping. - * - * @param ms number of milliseconds to sleep - */ -void -sys_msleep(u32_t ms) -{ - if (ms > 0) { - sys_sem_t delaysem; - err_t err = sys_sem_new(&delaysem, 0); - if (err == ERR_OK) { - sys_arch_sem_wait(&delaysem, ms); - sys_sem_free(&delaysem); - } - } -} - -/* sys_thread_new(): Spawns a new thread with given attributes as supportet - * Note: In MetalSVM this is realized as kernel tasks - */ -sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio) -{ -#ifdef WIN32 - bthread_t tmp; - bthread_attr_t tattr; - tattr.creation_flags = NULL; - tattr.thread_id = NULL; - tattr.stacksize = stacksize; - bthread_create(&tmp,NULL,thread,arg); - return tmp; -#else - tid_t tmp; - create_kernel_task(&tmp,thread,arg); - return tmp; -#endif -} - -/* sys_sem_free(): destroy's given semaphore - * and releases system resources. - * This semaphore also gets invalid. - */ -void sys_sem_free(sys_sem_t* sem) -{ - sem->valid = FALSE; - sem_destroy(&sem->sem); -} -/* sys_sem_valid(): returns if semaphore is valid - * at the moment - */ -int sys_sem_valid(sys_sem_t* sem) -{ - return sem->valid; -} - -/* sys_sem_new(): creates a new semaphre with given count. - * This semaphore becomes valid - */ -err_t sys_sem_new(sys_sem_t* sem,u8_t count) -{ - sem->valid = TRUE; - return sem_init(&sem->sem,count); -} -/* sys_sem_set_invalid(): this semapohore becomes invalid - * Note: this does not mean it is destroyed - */ -void sys_sem_set_invalid(sys_sem_t * sem) -{ - sem->valid = FALSE; -} - -/* sys_sem_signal(): this semaphore is signaled - * - */ -void sys_sem_signal(sys_sem_t* sem) -{ - sem_post(&sem->sem); -} -/* sys_arch_sem_wait): wait for the given semaphore for - * a given timeout - * Note: timeout = 0 means wait forever - */ -u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) -{ - int err; - if (!timeout) - return sem_wait(&sem->sem); - while (timeout) - { - err = sem_trywait(&sem->sem); -#ifdef WIN32 - if (err != 0x00000102L) - return err; -#else - if (err != -1) - return err; -#endif - timeout--; - } - return SYS_ARCH_TIMEOUT; -} - -/* sys_mbox_valid() : returns if the given mailbox - * is valid - */ -int sys_mbox_valid(sys_mbox_t * mbox) -{ - return mbox->valid; -} -/* sys_arch_mbox_fetch(): wait for the given mailbox for a specified - * amount of time. - * Note: timeout = 0 means wait forever - */ -u32_t sys_arch_mbox_fetch(sys_mbox_t * mbox, void **msg, u32_t timeout) -{ - int err = 0; - - if (!timeout) - return mailbox_ptr_fetch(&mbox->mailbox,msg); - - while(timeout) - { - if (!mailbox_ptr_tryfetch(&mbox->mailbox,msg)) - return 0; - timeout--; - } - return SYS_ARCH_TIMEOUT; - -} -/* sys_mbox_free() : free the given mailbox, release the system resources - * and set mbox to invalid - */ -void sys_mbox_free(sys_mbox_t* mbox) -{ - mbox->valid = FALSE; - mailbox_ptr_destroy(&mbox->mailbox); -} - -/* sys_arch_mbox_tryfetch(): poll for new data in mailbox - * - */ -u32_t sys_arch_mbox_tryfetch(sys_mbox_t* mbox, void** msg) -{ - return mailbox_ptr_tryfetch(&mbox->mailbox,msg); -} - -/* sys_mbox_new(): create a new mailbox with a minimum size of "size" - * - */ -err_t sys_mbox_new(sys_mbox_t* mbox,int size) -{ - mbox->valid = TRUE; - return mailbox_ptr_init(&mbox->mailbox); -} -/* sys_mbox_set_invalid(): set the given mailbox to invalid - * Note: system resources are NOT freed - */ -void sys_mbox_set_invalid(sys_mbox_t* mbox) -{ - mbox->valid =FALSE; -} -/* sys_mbox_trypost(): try to post data to the mailbox - * Note: There is at the moment no try post implemented - * so we use the normal post instead - */ -int sys_mbox_trypost(sys_mbox_t* mbox,void* msg) -{ - return mailbox_ptr_post(&mbox->mailbox,msg); -} - -/* sys_mbox_post(): post new data to the mailbox - * - */ -void sys_mbox_post(sys_mbox_t* mbox,void* msg) -{ - mailbox_ptr_post(&mbox->mailbox,msg); -} - -/* sys_mutex_lock(): lock the given mutex - * Note: There is no specific mutex in MetalSVM - * so we use a semaphore with 1 element - */ -void sys_mutex_lock(sys_mutex_t* mutex) -{ -#ifdef WIN32 - bthread_mutex_lock(mutex); -#else - sem_wait(mutex); -#endif -} - -/* sys_mutex_unlock(): unlock the given mutex - * - */ -void sys_mutex_unlock(sys_mutex_t* mutex) -{ -#ifdef WIN32 - bthread_mutex_unlock(mutex); -#else - sem_post(mutex); -#endif -} - -/* sys_mutex_new(): create a new mutex - * - */ -err_t sys_mutex_new(sys_mutex_t * mutex) -{ -#ifdef WIN32 - bthread_mutex_init(mutex); - return 0; -#else - sem_init(mutex,1); - return 0; -#endif -} - -/* sys_init(): init needed system resources - * Note: At the moment there are none - */ -void sys_init() -{ - return NULL; -} - -#endif /* !NO_SYS */ - - - - +/** + * @file + * lwIP Operating System abstraction + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/sys.h" + +/* Most of the functions defined in sys.h must be implemented in the + * architecture-dependent file sys_arch.c */ + +#if !NO_SYS + +/** + * Sleep for some ms. Timeouts are NOT processed while sleeping. + * + * @param ms number of milliseconds to sleep + */ +void +sys_msleep(u32_t ms) +{ + if (ms > 0) { + sys_sem_t delaysem; + err_t err = sys_sem_new(&delaysem, 0); + if (err == ERR_OK) { + sys_arch_sem_wait(&delaysem, ms); + sys_sem_free(&delaysem); + } + } +} + +#endif /* !NO_SYS */ diff --git a/lwip/src/core/tcp.c b/lwip/src/core/tcp.c index 8297b3ee..c629bc4e 100644 --- a/lwip/src/core/tcp.c +++ b/lwip/src/core/tcp.c @@ -91,7 +91,7 @@ struct tcp_pcb *tcp_tw_pcbs; #define NUM_TCP_PCB_LISTS 4 #define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3 /** An array with all (non-temporary) PCB lists, mainly used for smaller code size */ -struct tcp_pcb **tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs, +struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs, &tcp_active_pcbs, &tcp_tw_pcbs}; /** Only used for temporary storage. */ @@ -173,7 +173,9 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) * is erroneous, but this should never happen as the pcb has in those cases * been freed, and so any remaining handles are bogus. */ err = ERR_OK; - TCP_RMV(&tcp_bound_pcbs, pcb); + if (pcb->local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } memp_free(MEMP_TCP_PCB, pcb); pcb = NULL; break; @@ -391,6 +393,7 @@ tcp_abort(struct tcp_pcb *pcb) * to any local address * @param port the local port to bind to * @return ERR_USE if the port is already in use + * ERR_VAL if bind failed because the PCB is not in a valid state * ERR_OK if bound */ err_t @@ -400,7 +403,7 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) int max_pcb_list = NUM_TCP_PCB_LISTS; struct tcp_pcb *cpcb; - LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); + LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL); #if SO_REUSE /* Unless the REUSEADDR flag is set, @@ -440,7 +443,7 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) } if (!ip_addr_isany(ipaddr)) { - pcb->local_ip = *(ipaddr); + pcb->local_ip = *ipaddr; } pcb->local_port = port; TCP_REG(&tcp_bound_pcbs, pcb); @@ -516,7 +519,9 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) lpcb->ttl = pcb->ttl; lpcb->tos = pcb->tos; ip_addr_copy(lpcb->local_ip, pcb->local_ip); - TCP_RMV(&tcp_bound_pcbs, pcb); + if (pcb->local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } memp_free(MEMP_TCP_PCB, pcb); #if LWIP_CALLBACK_API lpcb->accept = tcp_accept_null; @@ -606,17 +611,19 @@ tcp_new_port(void) int i; struct tcp_pcb *pcb; #ifndef TCP_LOCAL_PORT_RANGE_START -#define TCP_LOCAL_PORT_RANGE_START 4096 -#define TCP_LOCAL_PORT_RANGE_END 0x7fff +/* From http://www.iana.org/assignments/port-numbers: + "The Dynamic and/or Private Ports are those from 49152 through 65535" */ +#define TCP_LOCAL_PORT_RANGE_START 0xc000 +#define TCP_LOCAL_PORT_RANGE_END 0xffff #endif static u16_t port = TCP_LOCAL_PORT_RANGE_START; again: - if (++port > TCP_LOCAL_PORT_RANGE_END) { + if (port++ >= TCP_LOCAL_PORT_RANGE_END) { port = TCP_LOCAL_PORT_RANGE_START; } /* Check all PCB lists. */ - for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { + for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) { if (pcb->local_port == port) { goto again; @@ -644,8 +651,9 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, { err_t ret; u32_t iss; + u16_t old_local_port; - LWIP_ERROR("tcp_connect: can only connected from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); + LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); if (ipaddr != NULL) { @@ -668,6 +676,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, ip_addr_copy(pcb->local_ip, netif->ip_addr); } + old_local_port = pcb->local_port; if (pcb->local_port == 0) { pcb->local_port = tcp_new_port(); } @@ -719,7 +728,9 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, if (ret == ERR_OK) { /* SYN segment was enqueued, changed the pcbs state now */ pcb->state = SYN_SENT; - TCP_RMV(&tcp_bound_pcbs, pcb); + if (old_local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } TCP_REG(&tcp_active_pcbs, pcb); snmp_inc_tcpactiveopens(); diff --git a/lwip/src/core/tcp_in.c b/lwip/src/core/tcp_in.c index 60ade915..90952648 100644 --- a/lwip/src/core/tcp_in.c +++ b/lwip/src/core/tcp_in.c @@ -291,7 +291,6 @@ tcp_input(struct pbuf *p, struct netif *inp) /* Set up a tcp_seg structure. */ inseg.next = NULL; inseg.len = p->tot_len; - inseg.dataptr = p->payload; inseg.p = p; inseg.tcphdr = tcphdr; @@ -1167,9 +1166,6 @@ tcp_receive(struct tcp_pcb *pcb) LWIP_ASSERT("pbuf_header failed", 0); } } - /* KJM following line changed to use p->payload rather than inseg->p->payload - to fix bug #9076 */ - inseg.dataptr = p->payload; inseg.len -= (u16_t)(pcb->rcv_nxt - seqno); inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; } diff --git a/lwip/src/core/tcp_in.c.orig b/lwip/src/core/tcp_in.c.orig deleted file mode 100644 index 3254276d..00000000 --- a/lwip/src/core/tcp_in.c.orig +++ /dev/null @@ -1,1483 +0,0 @@ -/** - * @file - * Transmission Control Protocol, incoming traffic - * - * The input processing functions of the TCP layer. - * - * These functions are generally called in the order (ip_input() ->) - * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/tcp.h" -#include "lwip/def.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/inet.h" -#include "lwip/inet_chksum.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "arch/perf.h" - -/* These variables are global to all functions involved in the input - processing of TCP segments. They are set by the tcp_input() - function. */ -static struct tcp_seg inseg; -static struct tcp_hdr *tcphdr; -static struct ip_hdr *iphdr; -static u32_t seqno, ackno; -static u8_t flags; -static u16_t tcplen; - -static u8_t recv_flags; -static struct pbuf *recv_data; - -struct tcp_pcb *tcp_input_pcb; - -/* Forward declarations. */ -static err_t tcp_process(struct tcp_pcb *pcb); -static void tcp_receive(struct tcp_pcb *pcb); -static void tcp_parseopt(struct tcp_pcb *pcb); - -static err_t tcp_listen_input(struct tcp_pcb_listen *pcb); -static err_t tcp_timewait_input(struct tcp_pcb *pcb); - -/** - * The initial input processing of TCP. It verifies the TCP header, demultiplexes - * the segment between the PCBs and passes it on to tcp_process(), which implements - * the TCP finite state machine. This function is called by the IP layer (in - * ip_input()). - * - * @param p received TCP segment to process (p->payload pointing to the IP header) - * @param inp network interface on which this segment was received - */ -void -tcp_input(struct pbuf *p, struct netif *inp) -{ - struct tcp_pcb *pcb, *prev; - struct tcp_pcb_listen *lpcb; - u8_t hdrlen; - err_t err; - - PERF_START; - - TCP_STATS_INC(tcp.recv); - snmp_inc_tcpinsegs(); - - iphdr = p->payload; - tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4); - -#if TCP_INPUT_DEBUG - tcp_debug_print(tcphdr); -#endif - - /* remove header from payload */ - if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) { - /* drop short packets */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); - TCP_STATS_INC(tcp.lenerr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; - } - - /* Don't even process incoming broadcasts/multicasts. */ - if (ip_addr_isbroadcast(&(iphdr->dest), inp) || - ip_addr_ismulticast(&(iphdr->dest))) { - TCP_STATS_INC(tcp.proterr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; - } - -#if CHECKSUM_CHECK_TCP - /* Verify TCP checksum. */ - if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), - (struct ip_addr *)&(iphdr->dest), - IP_PROTO_TCP, p->tot_len) != 0) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", - inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest), - IP_PROTO_TCP, p->tot_len))); -#if TCP_DEBUG - tcp_debug_print(tcphdr); -#endif /* TCP_DEBUG */ - TCP_STATS_INC(tcp.chkerr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; - } -#endif - - /* Move the payload pointer in the pbuf so that it points to the - TCP data instead of the TCP header. */ - hdrlen = TCPH_HDRLEN(tcphdr); - if(pbuf_header(p, -(hdrlen * 4))){ - /* drop short packets */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n")); - TCP_STATS_INC(tcp.lenerr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; - } - - /* Convert fields in TCP header to host byte order. */ - tcphdr->src = ntohs(tcphdr->src); - tcphdr->dest = ntohs(tcphdr->dest); - seqno = tcphdr->seqno = ntohl(tcphdr->seqno); - ackno = tcphdr->ackno = ntohl(tcphdr->ackno); - tcphdr->wnd = ntohs(tcphdr->wnd); - - flags = TCPH_FLAGS(tcphdr); - tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0); - - /* Demultiplex an incoming segment. First, we check if it is destined - for an active connection. */ - prev = NULL; - - - for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); - LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); - LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); - if (pcb->remote_port == tcphdr->src && - pcb->local_port == tcphdr->dest && - ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) && - ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) { - - /* Move this PCB to the front of the list so that subsequent - lookups will be faster (we exploit locality in TCP segment - arrivals). */ - LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); - if (prev != NULL) { - prev->next = pcb->next; - pcb->next = tcp_active_pcbs; - tcp_active_pcbs = pcb; - } - LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); - break; - } - prev = pcb; - } - - if (pcb == NULL) { - /* If it did not go to an active connection, we check the connections - in the TIME-WAIT state. */ - for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); - if (pcb->remote_port == tcphdr->src && - pcb->local_port == tcphdr->dest && - ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) && - ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) { - /* We don't really care enough to move this PCB to the front - of the list since we are not very likely to receive that - many segments for connections in TIME-WAIT. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); - tcp_timewait_input(pcb); - pbuf_free(p); - return; - } - } - - /* Finally, if we still did not get a match, we check all PCBs that - are LISTENing for incoming connections. */ - prev = NULL; - for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { - if ((ip_addr_isany(&(lpcb->local_ip)) || - ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) && - lpcb->local_port == tcphdr->dest) { - /* Move this PCB to the front of the list so that subsequent - lookups will be faster (we exploit locality in TCP segment - arrivals). */ - if (prev != NULL) { - ((struct tcp_pcb_listen *)prev)->next = lpcb->next; - /* our successor is the remainder of the listening list */ - lpcb->next = tcp_listen_pcbs.listen_pcbs; - /* put this listening pcb at the head of the listening list */ - tcp_listen_pcbs.listen_pcbs = lpcb; - } - - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); - tcp_listen_input(lpcb); - pbuf_free(p); - return; - } - prev = (struct tcp_pcb *)lpcb; - } - } - -#if TCP_INPUT_DEBUG - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags ")); - tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n")); -#endif /* TCP_INPUT_DEBUG */ - - - if (pcb != NULL) { - /* The incoming segment belongs to a connection. */ -#if TCP_INPUT_DEBUG -#if TCP_DEBUG - tcp_debug_print_state(pcb->state); -#endif /* TCP_DEBUG */ -#endif /* TCP_INPUT_DEBUG */ - - /* Set up a tcp_seg structure. */ - inseg.next = NULL; - inseg.len = p->tot_len; - inseg.dataptr = p->payload; - inseg.p = p; - inseg.tcphdr = tcphdr; - - recv_data = NULL; - recv_flags = 0; - - /* If there is data which was previously "refused" by upper layer */ - if (pcb->refused_data != NULL) { - /* Notify again application with data previously received. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); - TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err); - if (err == ERR_OK) { - pcb->refused_data = NULL; - } else { - /* drop incoming packets, because pcb is "full" */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; - } - } - tcp_input_pcb = pcb; - err = tcp_process(pcb); - /* A return value of ERR_ABRT means that tcp_abort() was called - and that the pcb has been freed. If so, we don't do anything. */ - if (err != ERR_ABRT) { - if (recv_flags & TF_RESET) { - /* TF_RESET means that the connection was reset by the other - end. We then call the error callback to inform the - application that the connection is dead before we - deallocate the PCB. */ - TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST); - tcp_pcb_remove(&tcp_active_pcbs, pcb); - memp_free(MEMP_TCP_PCB, pcb); - } else if (recv_flags & TF_CLOSED) { - /* The connection has been closed and we will deallocate the - PCB. */ - tcp_pcb_remove(&tcp_active_pcbs, pcb); - memp_free(MEMP_TCP_PCB, pcb); - } else { - err = ERR_OK; - /* If the application has registered a "sent" function to be - called when new send buffer space is available, we call it - now. */ - if (pcb->acked > 0) { - TCP_EVENT_SENT(pcb, pcb->acked, err); - } - - if (recv_data != NULL) { - if(flags & TCP_PSH) { - recv_data->flags |= PBUF_FLAG_PUSH; - } - - /* Notify application that data has been received. */ - TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); - - /* If the upper layer can't receive this data, store it */ - if (err != ERR_OK) { - pcb->refused_data = recv_data; - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n")); - } - } - - /* If a FIN segment was received, we call the callback - function with a NULL buffer to indicate EOF. */ - if (recv_flags & TF_GOT_FIN) { - TCP_EVENT_RECV(pcb, NULL, ERR_OK, err); - } - - tcp_input_pcb = NULL; - /* Try to send something out. */ - tcp_output(pcb); -#if TCP_INPUT_DEBUG -#if TCP_DEBUG - tcp_debug_print_state(pcb->state); -#endif /* TCP_DEBUG */ -#endif /* TCP_INPUT_DEBUG */ - } - } - tcp_input_pcb = NULL; - - - /* give up our reference to inseg.p */ - if (inseg.p != NULL) - { - pbuf_free(inseg.p); - inseg.p = NULL; - } - } else { - - /* If no matching PCB was found, send a TCP RST (reset) to the - sender. */ - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); - if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { - TCP_STATS_INC(tcp.proterr); - TCP_STATS_INC(tcp.drop); - tcp_rst(ackno, seqno + tcplen, - &(iphdr->dest), &(iphdr->src), - tcphdr->dest, tcphdr->src); - } - pbuf_free(p); - } - - LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); - PERF_STOP("tcp_input"); -} - -/** - * Called by tcp_input() when a segment arrives for a listening - * connection (from tcp_input()). - * - * @param pcb the tcp_pcb_listen for which a segment arrived - * @return ERR_OK if the segment was processed - * another err_t on error - * - * @note the return value is not (yet?) used in tcp_input() - * @note the segment which arrived is saved in global variables, therefore only the pcb - * involved is passed as a parameter to this function - */ -static err_t -tcp_listen_input(struct tcp_pcb_listen *pcb) -{ - struct tcp_pcb *npcb; - err_t rc; - - /* In the LISTEN state, we check for incoming SYN segments, - creates a new PCB, and responds with a SYN|ACK. */ - if (flags & TCP_ACK) { - /* For incoming segments with the ACK flag set, respond with a - RST. */ - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); - tcp_rst(ackno + 1, seqno + tcplen, - &(iphdr->dest), &(iphdr->src), - tcphdr->dest, tcphdr->src); - } else if (flags & TCP_SYN) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); -#if TCP_LISTEN_BACKLOG - if (pcb->accepts_pending >= pcb->backlog) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); - return ERR_ABRT; - } -#endif /* TCP_LISTEN_BACKLOG */ - npcb = tcp_alloc(pcb->prio); - /* If a new PCB could not be created (probably due to lack of memory), - we don't do anything, but rely on the sender will retransmit the - SYN at a time when we have more memory available. */ - if (npcb == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); - TCP_STATS_INC(tcp.memerr); - return ERR_MEM; - } -#if TCP_LISTEN_BACKLOG - pcb->accepts_pending++; -#endif /* TCP_LISTEN_BACKLOG */ - /* Set up the new PCB. */ - ip_addr_set(&(npcb->local_ip), &(iphdr->dest)); - npcb->local_port = pcb->local_port; - ip_addr_set(&(npcb->remote_ip), &(iphdr->src)); - npcb->remote_port = tcphdr->src; - npcb->state = SYN_RCVD; - npcb->rcv_nxt = seqno + 1; - npcb->rcv_ann_right_edge = npcb->rcv_nxt; - npcb->snd_wnd = tcphdr->wnd; - npcb->ssthresh = npcb->snd_wnd; - npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ - npcb->callback_arg = pcb->callback_arg; -#if LWIP_CALLBACK_API - npcb->accept = pcb->accept; -#endif /* LWIP_CALLBACK_API */ - /* inherit socket options */ - npcb->so_options = pcb->so_options & (SOF_DEBUG|SOF_DONTROUTE|SOF_KEEPALIVE|SOF_OOBINLINE|SOF_LINGER); - /* Register the new PCB so that we can begin receiving segments - for it. */ - TCP_REG(&tcp_active_pcbs, npcb); - - /* Parse any options in the SYN. */ - tcp_parseopt(npcb); -#if TCP_CALCULATE_EFF_SEND_MSS - npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip)); -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - - snmp_inc_tcppassiveopens(); - - /* Send a SYN|ACK together with the MSS option. */ - rc = tcp_enqueue(npcb, NULL, 0, TCP_SYN | TCP_ACK, 0, TF_SEG_OPTS_MSS -#if LWIP_TCP_TIMESTAMPS - /* and maybe include the TIMESTAMP option */ - | (npcb->flags & TF_TIMESTAMP ? TF_SEG_OPTS_TS : 0) -#endif - ); - if (rc != ERR_OK) { - tcp_abandon(npcb, 0); - return rc; - } - return tcp_output(npcb); - } - return ERR_OK; -} - -/** - * Called by tcp_input() when a segment arrives for a connection in - * TIME_WAIT. - * - * @param pcb the tcp_pcb for which a segment arrived - * - * @note the segment which arrived is saved in global variables, therefore only the pcb - * involved is passed as a parameter to this function - */ -static err_t -tcp_timewait_input(struct tcp_pcb *pcb) -{ - /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ - /* RFC 793 3.9 Event Processing - Segment Arrives: - * - first check sequence number - we skip that one in TIME_WAIT (always - * acceptable since we only send ACKs) - * - second check the RST bit (... return) */ - if (flags & TCP_RST) { - return ERR_OK; - } - /* - fourth, check the SYN bit, */ - if (flags & TCP_SYN) { - /* If an incoming segment is not acceptable, an acknowledgment - should be sent in reply */ - if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) { - /* If the SYN is in the window it is an error, send a reset */ - tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src), - tcphdr->dest, tcphdr->src); - return ERR_OK; - } - } else if (flags & TCP_FIN) { - /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. - Restart the 2 MSL time-wait timeout.*/ - pcb->tmr = tcp_ticks; - } - - if ((tcplen > 0)) { - /* Acknowledge data, FIN or out-of-window SYN */ - pcb->flags |= TF_ACK_NOW; - return tcp_output(pcb); - } - return ERR_OK; -} - -/** - * Implements the TCP state machine. Called by tcp_input. In some - * states tcp_receive() is called to receive data. The tcp_seg - * argument will be freed by the caller (tcp_input()) unless the - * recv_data pointer in the pcb is set. - * - * @param pcb the tcp_pcb for which a segment arrived - * - * @note the segment which arrived is saved in global variables, therefore only the pcb - * involved is passed as a parameter to this function - */ -static err_t -tcp_process(struct tcp_pcb *pcb) -{ - struct tcp_seg *rseg; - u8_t acceptable = 0; - err_t err; - - err = ERR_OK; - - /* Process incoming RST segments. */ - if (flags & TCP_RST) { - /* First, determine if the reset is acceptable. */ - if (pcb->state == SYN_SENT) { - if (ackno == pcb->snd_nxt) { - acceptable = 1; - } - } else { - if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, - pcb->rcv_nxt+pcb->rcv_wnd)) { - acceptable = 1; - } - } - - if (acceptable) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); - LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); - recv_flags |= TF_RESET; - pcb->flags &= ~TF_ACK_DELAY; - return ERR_RST; - } else { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", - seqno, pcb->rcv_nxt)); - LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", - seqno, pcb->rcv_nxt)); - return ERR_OK; - } - } - - if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { - /* Cope with new connection attempt after remote end crashed */ - tcp_ack_now(pcb); - return ERR_OK; - } - - /* Update the PCB (in)activity timer. */ - pcb->tmr = tcp_ticks; - pcb->keep_cnt_sent = 0; - - tcp_parseopt(pcb); - - /* Do different things depending on the TCP state. */ - switch (pcb->state) { - case SYN_SENT: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, - pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno))); - /* received SYN ACK with expected sequence number? */ - if ((flags & TCP_ACK) && (flags & TCP_SYN) - && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) { - pcb->snd_buf++; - pcb->rcv_nxt = seqno + 1; - pcb->rcv_ann_right_edge = pcb->rcv_nxt; - pcb->lastack = ackno; - pcb->snd_wnd = tcphdr->wnd; - pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ - pcb->state = ESTABLISHED; - -#if TCP_CALCULATE_EFF_SEND_MSS - pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip)); -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - - /* Set ssthresh again after changing pcb->mss (already set in tcp_connect - * but for the default value of pcb->mss) */ - pcb->ssthresh = pcb->mss * 10; - - pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss); - LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); - --pcb->snd_queuelen; - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen)); - rseg = pcb->unacked; - pcb->unacked = rseg->next; - - /* If there's nothing left to acknowledge, stop the retransmit - timer, otherwise reset it to start again */ - if(pcb->unacked == NULL) - pcb->rtime = -1; - else { - pcb->rtime = 0; - pcb->nrtx = 0; - } - - tcp_seg_free(rseg); - - /* Call the user specified function to call when sucessfully - * connected. */ - TCP_EVENT_CONNECTED(pcb, ERR_OK, err); - tcp_ack_now(pcb); - } - /* received ACK? possibly a half-open connection */ - else if (flags & TCP_ACK) { - /* send a RST to bring the other side in a non-synchronized state. */ - tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src), - tcphdr->dest, tcphdr->src); - } - break; - case SYN_RCVD: - if (flags & TCP_ACK) { - /* expected ACK number? */ - if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { - u16_t old_cwnd; - pcb->state = ESTABLISHED; - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); -#if LWIP_CALLBACK_API - LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL); -#endif - /* Call the accept function. */ - TCP_EVENT_ACCEPT(pcb, ERR_OK, err); - if (err != ERR_OK) { - /* If the accept function returns with an error, we abort - * the connection. */ - tcp_abort(pcb); - return ERR_ABRT; - } - old_cwnd = pcb->cwnd; - /* If there was any data contained within this ACK, - * we'd better pass it on to the application as well. */ - tcp_receive(pcb); - - /* Prevent ACK for SYN to generate a sent event */ - if (pcb->acked != 0) { - pcb->acked--; - } - - pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss); - - if (recv_flags & TF_GOT_FIN) { - tcp_ack_now(pcb); - pcb->state = CLOSE_WAIT; - } - } - /* incorrect ACK number */ - else { - /* send RST */ - tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src), - tcphdr->dest, tcphdr->src); - } - } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { - /* Looks like another copy of the SYN - retransmit our SYN-ACK */ - tcp_rexmit(pcb); - } - break; - case CLOSE_WAIT: - /* FALLTHROUGH */ - case ESTABLISHED: - tcp_receive(pcb); - if (recv_flags & TF_GOT_FIN) { /* passive close */ - tcp_ack_now(pcb); - pcb->state = CLOSE_WAIT; - } - break; - case FIN_WAIT_1: - tcp_receive(pcb); - if (recv_flags & TF_GOT_FIN) { - if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { - LWIP_DEBUGF(TCP_DEBUG, - ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - tcp_ack_now(pcb); - tcp_pcb_purge(pcb); - TCP_RMV(&tcp_active_pcbs, pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } else { - tcp_ack_now(pcb); - pcb->state = CLOSING; - } - } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { - pcb->state = FIN_WAIT_2; - } - break; - case FIN_WAIT_2: - tcp_receive(pcb); - if (recv_flags & TF_GOT_FIN) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - tcp_ack_now(pcb); - tcp_pcb_purge(pcb); - TCP_RMV(&tcp_active_pcbs, pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } - break; - case CLOSING: - tcp_receive(pcb); - if (flags & TCP_ACK && ackno == pcb->snd_nxt) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - tcp_pcb_purge(pcb); - TCP_RMV(&tcp_active_pcbs, pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } - break; - case LAST_ACK: - tcp_receive(pcb); - if (flags & TCP_ACK && ackno == pcb->snd_nxt) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ - recv_flags |= TF_CLOSED; - } - break; - default: - break; - } - return ERR_OK; -} - -#if TCP_QUEUE_OOSEQ -/** - * Insert segment into the list (segments covered with new one will be deleted) - * - * Called from tcp_receive() - */ -static void -tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) -{ - if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { - /* received segment overlaps all following segments */ - tcp_segs_free(next); - next = NULL; - } - else { - /* delete some following segments - oos queue may have segments with FIN flag */ - while (next && - TCP_SEQ_GEQ((seqno + cseg->len), - (next->tcphdr->seqno + next->len))) { - /* cseg with FIN already processed */ - if (TCPH_FLAGS(next->mpTcpHdr) & TCP_FIN) { - TCPH_FLAGS_SET(cseg->tcphdr, TCPH_FLAGS(cseg->tcphdr) | TCP_FIN); - } - struct tcp_seg *old_seg = next; - next = next->next; - tcp_seg_free(old_seg); - } - if (next && - TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { - /* We need to trim the incoming segment. */ - cseg->len = (u16_t)(next->tcphdr->seqno - seqno); - pbuf_realloc(cseg->p, cseg->len); - } - } - cseg->next = next; -} -#endif - -/** - * Called by tcp_process. Checks if the given segment is an ACK for outstanding - * data, and if so frees the memory of the buffered data. Next, is places the - * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment - * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until - * i it has been removed from the buffer. - * - * If the incoming segment constitutes an ACK for a segment that was used for RTT - * estimation, the RTT is estimated here as well. - * - * Called from tcp_process(). - */ -static void -tcp_receive(struct tcp_pcb *pcb) -{ - struct tcp_seg *next; -#if TCP_QUEUE_OOSEQ - struct tcp_seg *prev, *cseg; -#endif - struct pbuf *p; - s32_t off; - s16_t m; - u32_t right_wnd_edge; - u16_t new_tot_len; - int found_dupack = 0; - - if (flags & TCP_ACK) { - right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; - - /* Update window. */ - if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || - (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || - (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) { - pcb->snd_wnd = tcphdr->wnd; - pcb->snd_wl1 = seqno; - pcb->snd_wl2 = ackno; - if (pcb->snd_wnd > 0 && pcb->persist_backoff > 0) { - pcb->persist_backoff = 0; - } - LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd)); -#if TCP_WND_DEBUG - } else { - if (pcb->snd_wnd != tcphdr->wnd) { - LWIP_DEBUGF(TCP_WND_DEBUG, - ("tcp_receive: no window update lastack %"U32_F" ackno %" - U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n", - pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); - } -#endif /* TCP_WND_DEBUG */ - } - - /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a - * duplicate ack if: - * 1) It doesn't ACK new data - * 2) length of received packet is zero (i.e. no payload) - * 3) the advertised window hasn't changed - * 4) There is outstanding unacknowledged data (retransmission timer running) - * 5) The ACK is == biggest ACK sequence number so far seen (snd_una) - * - * If it passes all five, should process as a dupack: - * a) dupacks < 3: do nothing - * b) dupacks == 3: fast retransmit - * c) dupacks > 3: increase cwnd - * - * If it only passes 1-3, should reset dupack counter (and add to - * stats, which we don't do in lwIP) - * - * If it only passes 1, should reset dupack counter - * - */ - - /* Clause 1 */ - if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { - pcb->acked = 0; - /* Clause 2 */ - if (tcplen == 0) { - /* Clause 3 */ - if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){ - /* Clause 4 */ - if (pcb->rtime >= 0) { - /* Clause 5 */ - if (pcb->lastack == ackno) { - found_dupack = 1; - if (pcb->dupacks + 1 > pcb->dupacks) - ++pcb->dupacks; - if (pcb->dupacks > 3) { - /* Inflate the congestion window, but not if it means that - the value overflows. */ - if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { - pcb->cwnd += pcb->mss; - } - } else if (pcb->dupacks == 3) { - /* Do fast retransmit */ - tcp_rexmit_fast(pcb); - } - } - } - } - } - /* If Clause (1) or more is true, but not a duplicate ack, reset - * count of consecutive duplicate acks */ - if (!found_dupack) { - pcb->dupacks = 0; - } - } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){ - /* We come here when the ACK acknowledges new data. */ - - /* Reset the "IN Fast Retransmit" flag, since we are no longer - in fast retransmit. Also reset the congestion window to the - slow start threshold. */ - if (pcb->flags & TF_INFR) { - pcb->flags &= ~TF_INFR; - pcb->cwnd = pcb->ssthresh; - } - - /* Reset the number of retransmissions. */ - pcb->nrtx = 0; - - /* Reset the retransmission time-out. */ - pcb->rto = (pcb->sa >> 3) + pcb->sv; - - /* Update the send buffer space. Diff between the two can never exceed 64K? */ - pcb->acked = (u16_t)(ackno - pcb->lastack); - - pcb->snd_buf += pcb->acked; - - /* Reset the fast retransmit variables. */ - pcb->dupacks = 0; - pcb->lastack = ackno; - - /* Update the congestion control variables (cwnd and - ssthresh). */ - if (pcb->state >= ESTABLISHED) { - if (pcb->cwnd < pcb->ssthresh) { - if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { - pcb->cwnd += pcb->mss; - } - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd)); - } else { - u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); - if (new_cwnd > pcb->cwnd) { - pcb->cwnd = new_cwnd; - } - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd)); - } - } - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n", - ackno, - pcb->unacked != NULL? - ntohl(pcb->unacked->tcphdr->seqno): 0, - pcb->unacked != NULL? - ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0)); - - /* Remove segment from the unacknowledged list if the incoming - ACK acknowlegdes them. */ - while (pcb->unacked != NULL && - TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) + - TCP_TCPLEN(pcb->unacked), ackno)) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n", - ntohl(pcb->unacked->tcphdr->seqno), - ntohl(pcb->unacked->tcphdr->seqno) + - TCP_TCPLEN(pcb->unacked))); - - next = pcb->unacked; - pcb->unacked = pcb->unacked->next; - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); - LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); - /* Prevent ACK for FIN to generate a sent event */ - if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { - pcb->acked--; - } - - pcb->snd_queuelen -= pbuf_clen(next->p); - tcp_seg_free(next); - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || - pcb->unsent != NULL); - } - } - - /* If there's nothing left to acknowledge, stop the retransmit - timer, otherwise reset it to start again */ - if(pcb->unacked == NULL) - pcb->rtime = -1; - else - pcb->rtime = 0; - - pcb->polltmr = 0; - } else { - /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */ - pcb->acked = 0; - } - - /* We go through the ->unsent list to see if any of the segments - on the list are acknowledged by the ACK. This may seem - strange since an "unsent" segment shouldn't be acked. The - rationale is that lwIP puts all outstanding segments on the - ->unsent list after a retransmission, so these segments may - in fact have been sent once. */ - while (pcb->unsent != NULL && - TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + - TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n", - ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) + - TCP_TCPLEN(pcb->unsent))); - - next = pcb->unsent; - pcb->unsent = pcb->unsent->next; - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); - LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); - /* Prevent ACK for FIN to generate a sent event */ - if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { - pcb->acked--; - } - pcb->snd_queuelen -= pbuf_clen(next->p); - tcp_seg_free(next); - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_receive: valid queue length", - pcb->unacked != NULL || pcb->unsent != NULL); - } - } - /* End of ACK for new data processing. */ - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n", - pcb->rttest, pcb->rtseq, ackno)); - - /* RTT estimation calculations. This is done by checking if the - incoming segment acknowledges the segment we use to take a - round-trip time measurement. */ - if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { - /* diff between this shouldn't exceed 32K since this are tcp timer ticks - and a round-trip shouldn't be that long... */ - m = (s16_t)(tcp_ticks - pcb->rttest); - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", - m, m * TCP_SLOW_INTERVAL)); - - /* This is taken directly from VJs original code in his paper */ - m = m - (pcb->sa >> 3); - pcb->sa += m; - if (m < 0) { - m = -m; - } - m = m - (pcb->sv >> 2); - pcb->sv += m; - pcb->rto = (pcb->sa >> 3) + pcb->sv; - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", - pcb->rto, pcb->rto * TCP_SLOW_INTERVAL)); - - pcb->rttest = 0; - } - } - - /* If the incoming segment contains data, we must process it - further. */ - if (tcplen > 0) { - /* This code basically does three things: - - +) If the incoming segment contains data that is the next - in-sequence data, this data is passed to the application. This - might involve trimming the first edge of the data. The rcv_nxt - variable and the advertised window are adjusted. - - +) If the incoming segment has data that is above the next - sequence number expected (->rcv_nxt), the segment is placed on - the ->ooseq queue. This is done by finding the appropriate - place in the ->ooseq queue (which is ordered by sequence - number) and trim the segment in both ends if needed. An - immediate ACK is sent to indicate that we received an - out-of-sequence segment. - - +) Finally, we check if the first segment on the ->ooseq queue - now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If - rcv_nxt > ooseq->seqno, we must trim the first edge of the - segment on ->ooseq before we adjust rcv_nxt. The data in the - segments that are now on sequence are chained onto the - incoming segment so that we only need to call the application - once. - */ - - /* First, we check if we must trim the first edge. We have to do - this if the sequence number of the incoming segment is less - than rcv_nxt, and the sequence number plus the length of the - segment is larger than rcv_nxt. */ - /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ - if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ - if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){ - /* Trimming the first edge is done by pushing the payload - pointer in the pbuf downwards. This is somewhat tricky since - we do not want to discard the full contents of the pbuf up to - the new starting point of the data since we have to keep the - TCP header which is present in the first pbuf in the chain. - - What is done is really quite a nasty hack: the first pbuf in - the pbuf chain is pointed to by inseg.p. Since we need to be - able to deallocate the whole pbuf, we cannot change this - inseg.p pointer to point to any of the later pbufs in the - chain. Instead, we point the ->payload pointer in the first - pbuf to data in one of the later pbufs. We also set the - inseg.data pointer to point to the right place. This way, the - ->p pointer will still point to the first pbuf, but the - ->p->payload pointer will point to data in another pbuf. - - After we are done with adjusting the pbuf pointers we must - adjust the ->data pointer in the seg and the segment - length.*/ - - off = pcb->rcv_nxt - seqno; - p = inseg.p; - LWIP_ASSERT("inseg.p != NULL", inseg.p); - LWIP_ASSERT("insane offset!", (off < 0x7fff)); - if (inseg.p->len < off) { - LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); - new_tot_len = (u16_t)(inseg.p->tot_len - off); - while (p->len < off) { - off -= p->len; - /* KJM following line changed (with addition of new_tot_len var) - to fix bug #9076 - inseg.p->tot_len -= p->len; */ - p->tot_len = new_tot_len; - p->len = 0; - p = p->next; - } - if(pbuf_header(p, (s16_t)-off)) { - /* Do we need to cope with this failing? Assert for now */ - LWIP_ASSERT("pbuf_header failed", 0); - } - } else { - if(pbuf_header(inseg.p, (s16_t)-off)) { - /* Do we need to cope with this failing? Assert for now */ - LWIP_ASSERT("pbuf_header failed", 0); - } - } - /* KJM following line changed to use p->payload rather than inseg->p->payload - to fix bug #9076 */ - inseg.dataptr = p->payload; - inseg.len -= (u16_t)(pcb->rcv_nxt - seqno); - inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; - } - else { - if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ - /* the whole segment is < rcv_nxt */ - /* must be a duplicate of a packet that has already been correctly handled */ - - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); - tcp_ack_now(pcb); - } - } - - /* The sequence number must be within the window (above rcv_nxt - and below rcv_nxt + rcv_wnd) in order to be further - processed. */ - if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, - pcb->rcv_nxt + pcb->rcv_wnd - 1)){ - if (pcb->rcv_nxt == seqno) { - /* The incoming segment is the next in sequence. We check if - we have to trim the end of the segment and update rcv_nxt - and pass the data to the application. */ - tcplen = TCP_TCPLEN(&inseg); - - if (tcplen > pcb->rcv_wnd) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, - ("tcp_receive: other end overran receive window" - "seqno %"U32_F" len %"U32_F" right edge %"U32_F"\n", - seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); - if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { - /* Must remove the FIN from the header as we're trimming - * that byte of sequence-space from the packet */ - TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN); - } - /* Adjust length of segment to fit in the window. */ - inseg.len = pcb->rcv_wnd; - if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { - inseg.len -= 1; - } - pbuf_realloc(inseg.p, inseg.len); - tcplen = TCP_TCPLEN(&inseg); - LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", - (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); - } -#if TCP_QUEUE_OOSEQ - if (pcb->ooseq != NULL) { - if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, - ("tcp_receive: received in-order FIN, binning ooseq queue\n")); - /* Received in-order FIN means anything that was received - * out of order must now have been received in-order, so - * bin the ooseq queue */ - while (pcb->ooseq != NULL) { - struct tcp_seg *old_ooseq = pcb->ooseq; - pcb->ooseq = pcb->ooseq->next; - tcp_seg_free(old_ooseq); - } - } else if (TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + tcplen)) { - if (pcb->ooseq->len > 0) { - /* We have to trim the second edge of the incoming segment. */ - LWIP_ASSERT("tcp_receive: trimmed segment would have zero length\n", - TCP_SEQ_GT(pcb->ooseq->tcphdr->seqno, seqno)); - /* FIN in inseg already handled by dropping whole ooseq queue */ - inseg.len = (u16_t)(pcb->ooseq->tcphdr->seqno - seqno); - if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { - inseg.len -= 1; - } - pbuf_realloc(inseg.p, inseg.len); - tcplen = TCP_TCPLEN(&inseg); - LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", - (seqno + tcplen) == pcb->ooseq->tcphdr->seqno); - } else { - /* does the ooseq segment contain only flags that are in inseg also? */ - if ((TCPH_FLAGS(inseg.tcphdr) & (TCP_FIN|TCP_SYN)) == - (TCPH_FLAGS(pcb->ooseq->tcphdr) & (TCP_FIN|TCP_SYN))) { - struct tcp_seg *old_ooseq = pcb->ooseq; - pcb->ooseq = pcb->ooseq->next; - tcp_seg_free(old_ooseq); - } - } - } - } -#endif /* TCP_QUEUE_OOSEQ */ - - pcb->rcv_nxt = seqno + tcplen; - - /* Update the receiver's (our) window. */ - LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); - pcb->rcv_wnd -= tcplen; - - tcp_update_rcv_ann_wnd(pcb); - - /* If there is data in the segment, we make preparations to - pass this up to the application. The ->recv_data variable - is used for holding the pbuf that goes to the - application. The code for reassembling out-of-sequence data - chains its data on this pbuf as well. - - If the segment was a FIN, we set the TF_GOT_FIN flag that will - be used to indicate to the application that the remote side has - closed its end of the connection. */ - if (inseg.p->tot_len > 0) { - recv_data = inseg.p; - /* Since this pbuf now is the responsibility of the - application, we delete our reference to it so that we won't - (mistakingly) deallocate it. */ - inseg.p = NULL; - } - if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); - recv_flags |= TF_GOT_FIN; - } - -#if TCP_QUEUE_OOSEQ - /* We now check if we have segments on the ->ooseq queue that - is now in sequence. */ - while (pcb->ooseq != NULL && - pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { - - cseg = pcb->ooseq; - seqno = pcb->ooseq->tcphdr->seqno; - - pcb->rcv_nxt += TCP_TCPLEN(cseg); - LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", - pcb->rcv_wnd >= TCP_TCPLEN(cseg)); - pcb->rcv_wnd -= TCP_TCPLEN(cseg); - - tcp_update_rcv_ann_wnd(pcb); - - if (cseg->p->tot_len > 0) { - /* Chain this pbuf onto the pbuf that we will pass to - the application. */ - if (recv_data) { - pbuf_cat(recv_data, cseg->p); - } else { - recv_data = cseg->p; - } - cseg->p = NULL; - } - if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); - recv_flags |= TF_GOT_FIN; - if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ - pcb->state = CLOSE_WAIT; - } - } - - pcb->ooseq = cseg->next; - tcp_seg_free(cseg); - } -#endif /* TCP_QUEUE_OOSEQ */ - - - /* Acknowledge the segment(s). */ - tcp_ack(pcb); - - } else { - /* We get here if the incoming segment is out-of-sequence. */ - tcp_send_empty_ack(pcb); -#if TCP_QUEUE_OOSEQ - /* We queue the segment on the ->ooseq queue. */ - if (pcb->ooseq == NULL) { - pcb->ooseq = tcp_seg_copy(&inseg); - } else { - /* If the queue is not empty, we walk through the queue and - try to find a place where the sequence number of the - incoming segment is between the sequence numbers of the - previous and the next segment on the ->ooseq queue. That is - the place where we put the incoming segment. If needed, we - trim the second edges of the previous and the incoming - segment so that it will fit into the sequence. - - If the incoming segment has the same sequence number as a - segment on the ->ooseq queue, we discard the segment that - contains less data. */ - - prev = NULL; - for(next = pcb->ooseq; next != NULL; next = next->next) { - if (seqno == next->tcphdr->seqno) { - /* The sequence number of the incoming segment is the - same as the sequence number of the segment on - ->ooseq. We check the lengths to see which one to - discard. */ - if (inseg.len > next->len) { - /* The incoming segment is larger than the old - segment. We replace some segments with the new - one. */ - cseg = tcp_seg_copy(&inseg); - if (cseg != NULL) { - if (prev != NULL) { - prev->next = cseg; - } else { - pcb->ooseq = cseg; - } - tcp_oos_insert_segment(cseg, next); - } - break; - } else { - /* Either the lenghts are the same or the incoming - segment was smaller than the old one; in either - case, we ditch the incoming segment. */ - break; - } - } else { - if (prev == NULL) { - if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { - /* The sequence number of the incoming segment is lower - than the sequence number of the first segment on the - queue. We put the incoming segment first on the - queue. */ - cseg = tcp_seg_copy(&inseg); - if (cseg != NULL) { - pcb->ooseq = cseg; - tcp_oos_insert_segment(cseg, next); - } - break; - } - } else { - /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && - TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ - if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) { - /* The sequence number of the incoming segment is in - between the sequence numbers of the previous and - the next segment on ->ooseq. We trim trim the previous - segment, delete next segments that included in received segment - and trim received, if needed. */ - cseg = tcp_seg_copy(&inseg); - if (cseg != NULL) { - if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { - /* We need to trim the prev segment. */ - prev->len = (u16_t)(seqno - prev->tcphdr->seqno); - pbuf_realloc(prev->p, prev->len); - } - prev->next = cseg; - tcp_oos_insert_segment(cseg, next); - } - break; - } - } - /* If the "next" segment is the last segment on the - ooseq queue, we add the incoming segment to the end - of the list. */ - if (next->next == NULL && - TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { - if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { - /* segment "next" already contains all data */ - break; - } - next->next = tcp_seg_copy(&inseg); - if (next->next != NULL) { - if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { - /* We need to trim the last segment. */ - next->len = (u16_t)(seqno - next->tcphdr->seqno); - pbuf_realloc(next->p, next->len); - } - } - break; - } - } - prev = next; - } - } -#endif /* TCP_QUEUE_OOSEQ */ - - } - } else { - /* The incoming segment is not withing the window. */ - tcp_send_empty_ack(pcb); - } - } else { - /* Segments with length 0 is taken care of here. Segments that - fall out of the window are ACKed. */ - /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) || - TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/ - if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){ - tcp_ack_now(pcb); - } - } -} - -/** - * Parses the options contained in the incoming segment. - * - * Called from tcp_listen_input() and tcp_process(). - * Currently, only the MSS option is supported! - * - * @param pcb the tcp_pcb for which a segment arrived - */ -static void -tcp_parseopt(struct tcp_pcb *pcb) -{ - u16_t c, max_c; - u16_t mss; - u8_t *opts, opt; -#if LWIP_TCP_TIMESTAMPS - u32_t tsval; -#endif - - opts = (u8_t *)tcphdr + TCP_HLEN; - - /* Parse the TCP MSS option, if present. */ - if(TCPH_HDRLEN(tcphdr) > 0x5) { - max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2; - for (c = 0; c < max_c; ) { - opt = opts[c]; - switch (opt) { - case 0x00: - /* End of options. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); - return; - case 0x01: - /* NOP option. */ - ++c; - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); - break; - case 0x02: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); - if (opts[c + 1] != 0x04 || c + 0x04 > max_c) { - /* Bad length */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - return; - } - /* An MSS option with the right option length. */ - mss = (opts[c + 2] << 8) | opts[c + 3]; - /* Limit the mss to the configured TCP_MSS and prevent division by zero */ - pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; - /* Advance to next option */ - c += 0x04; - break; -#if LWIP_TCP_TIMESTAMPS - case 0x08: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n")); - if (opts[c + 1] != 0x0A || c + 0x0A > max_c) { - /* Bad length */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - return; - } - /* TCP timestamp option with valid length */ - tsval = (opts[c+2]) | (opts[c+3] << 8) | - (opts[c+4] << 16) | (opts[c+5] << 24); - if (flags & TCP_SYN) { - pcb->ts_recent = ntohl(tsval); - pcb->flags |= TF_TIMESTAMP; - } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) { - pcb->ts_recent = ntohl(tsval); - } - /* Advance to next option */ - c += 0x0A; - break; -#endif - default: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); - if (opts[c + 1] == 0) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - /* If the length field is zero, the options are malformed - and we don't process them further. */ - return; - } - /* All other options have a length field, so that we easily - can skip past them. */ - c += opts[c + 1]; - } - } - } -} - -#endif /* LWIP_TCP */ diff --git a/lwip/src/core/tcp_out.c b/lwip/src/core/tcp_out.c index 32729081..86e09195 100644 --- a/lwip/src/core/tcp_out.c +++ b/lwip/src/core/tcp_out.c @@ -166,7 +166,6 @@ tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, seg->flags = optflags; seg->next = NULL; seg->p = p; - seg->dataptr = p->payload; seg->len = p->tot_len - optlen; #if TCP_OVERSIZE_DBGCHECK seg->oversize_left = 0; @@ -590,10 +589,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) seg->chksum_swapped = chksum_swapped; seg->flags |= TF_SEG_DATA_CHECKSUMMED; #endif /* TCP_CHECKSUM_ON_COPY */ - /* Fix dataptr for the nocopy case */ - if ((apiflags & TCP_WRITE_FLAG_COPY) == 0) { - seg->dataptr = (u8_t*)arg + pos; - } /* first segment of to-be-queued data? */ if (queue == NULL) { @@ -1083,6 +1078,12 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) } #endif + /* Set retransmission timer running if it is not currently enabled + This must be set before checking the route. */ + if (pcb->rtime == -1) { + pcb->rtime = 0; + } + /* If we don't have a local IP address, we get one by calling ip_route(). */ if (ip_addr_isany(&(pcb->local_ip))) { @@ -1093,11 +1094,6 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) ip_addr_copy(pcb->local_ip, netif->ip_addr); } - /* Set retransmission timer running if it is not currently enabled */ - if(pcb->rtime == -1) { - pcb->rtime = 0; - } - if (pcb->rttest == 0) { pcb->rttest = tcp_ticks; pcb->rtseq = ntohl(seg->tcphdr->seqno); @@ -1444,7 +1440,9 @@ tcp_zero_window_probe(struct tcp_pcb *pcb) TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN); } else { /* Data segment, copy in one byte from the head of the unacked queue */ - *((char *)p->payload + TCP_HLEN) = *(char *)seg->dataptr; + struct tcp_hdr *thdr = (struct tcp_hdr *)seg->p->payload; + char *d = ((char *)p->payload + TCP_HLEN); + pbuf_copy_partial(seg->p, d, 1, TCPH_HDRLEN(thdr) * 4); } #if CHECKSUM_GEN_TCP diff --git a/lwip/src/core/timers.c b/lwip/src/core/timers.c index 8361fc90..f0e92cce 100644 --- a/lwip/src/core/timers.c +++ b/lwip/src/core/timers.c @@ -292,8 +292,6 @@ sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg) next_timeout = timeout; } else { for(t = next_timeout; t != NULL; t = t->next) { - if (t->time ==0) - t->time = 1; timeout->time -= t->time; if (t->next == NULL || t->next->time > timeout->time) { if (t->next != NULL) { diff --git a/lwip/src/core/udp.c b/lwip/src/core/udp.c index 528c8653..4596ba2b 100644 --- a/lwip/src/core/udp.c +++ b/lwip/src/core/udp.c @@ -746,8 +746,10 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) /* no port specified? */ if (port == 0) { #ifndef UDP_LOCAL_PORT_RANGE_START -#define UDP_LOCAL_PORT_RANGE_START 4096 -#define UDP_LOCAL_PORT_RANGE_END 0x7fff +/* From http://www.iana.org/assignments/port-numbers: + "The Dynamic and/or Private Ports are those from 49152 through 65535" */ +#define UDP_LOCAL_PORT_RANGE_START 0xc000 +#define UDP_LOCAL_PORT_RANGE_END 0xffff #endif port = UDP_LOCAL_PORT_RANGE_START; ipcb = udp_pcbs; diff --git a/lwip/src/include/arch/cc.h b/lwip/src/include/arch/cc.h index 0f2da7f9..94fb22ee 100644 --- a/lwip/src/include/arch/cc.h +++ b/lwip/src/include/arch/cc.h @@ -1,86 +1,85 @@ - - -#ifndef __ARCH_CC_H__ -#define __ARCH_CC_H__ - -#include "sys_arch.h" - - -#ifdef WIN32 -#include -#else -#include -#include -#include -#endif - -//#include -//#include -//#include - -#define BYTE_ORDER LITTLE_ENDIAN - -#ifdef WIN32 - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; - -typedef char int8_t; -typedef short int16_t; -typedef int int32_t; -/* -typedef struct ___ip_addr_t { - union { - struct { uint8_t s_b1,s_b2,s_b3,s_b4; } S_un_b; - struct { uint16_t s_w1,s_w2; } S_un_w; - uint32_t addr; - }; -}ip_addr_t; -*/ -/* -typedef struct ___ip_addr_t -{ - uint32_t addr; -}ip_addr_t; -*/ - -#endif - -typedef uint8_t u8_t; -typedef int8_t s8_t; -typedef uint16_t u16_t; -typedef int16_t s16_t; -typedef uint32_t u32_t; -typedef int32_t s32_t; - -typedef unsigned mem_ptr_t; - -#define LWIP_ERR_T int - -/* Define (sn)printf formatters for these lwIP types */ -#define U16_F "hu" -#define S16_F "hd" -#define X16_F "hx" -#define U32_F "u" -#define S32_F "d" -#define X32_F "x" - -/* Compiler hints for packing structures */ -#define PACK_STRUCT_FIELD(x) x -#define PACK_STRUCT_STRUCT /*__attribute__((packed))*/ -#define PACK_STRUCT_BEGIN -#define PACK_STRUCT_END - -/* Plaform specific diagnostic output */ -#define LWIP_PLATFORM_DIAG(x) do { \ - kprintf(x); \ - } while (0) - -#define LWIP_PLATFORM_ASSERT(x) do { \ - kprintf("Assert \"%s\" failed at line %d in %s\n", \ - x, __LINE__, __FILE__); \ - return NULL; \ - } while (0) - -#endif /* __ARCH_CC_H__ */ \ No newline at end of file +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __ARCH_CC_H__ +#define __ARCH_CC_H__ + +/* Include some files for defining library routines */ +#include +//#include + +/* Define platform endianness */ +#ifndef BYTE_ORDER +#define BYTE_ORDER LITTLE_ENDIAN +#endif /* BYTE_ORDER */ + +/* Define generic types used in lwIP */ +typedef uint8_t u8_t; +typedef int8_t s8_t; +typedef uint16_t u16_t; +typedef int16_t s16_t; +typedef uint32_t u32_t; +typedef int32_t s32_t; + +typedef size_t mem_ptr_t; + +/* Define (sn)printf formatters for these lwIP types */ +#define X8_F "02x" +#define U16_F "hu" +#define S16_F "hd" +#define X16_F "hx" +#define U32_F "lu" +#define S32_F "ld" +#define X32_F "lx" + +/* Compiler hints for packing structures */ +//#define PACK_STRUCT_FIELD(x) x __attribute__((packed)) +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_STRUCT __attribute__((packed)) +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_END + +#define MEM_ALIGNMENT 4 +#define ETH_PAD_SIZE 2 + +#define LWIP_CHKSUM_ALGORITHM 2 + +/* prototypes for printf() and abort() */ +#include +#include + +/* Plaform specific diagnostic output */ +#define LWIP_PLATFORM_DIAG(x) do {kprintf x;} while(0) + +#define LWIP_PLATFORM_ASSERT(x) do {kprintf("Assertion \"%s\" failed at line %d in %s\n", \ + x, __LINE__, __FILE__); abort();} while(0) + +#endif /* __ARCH_CC_H__ */ diff --git a/lwip/src/include/arch/perf.h b/lwip/src/include/arch/perf.h index e18c8f63..36ff4cbc 100644 --- a/lwip/src/include/arch/perf.h +++ b/lwip/src/include/arch/perf.h @@ -1,63 +1,63 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __ARCH_PERF_H__ -#define __ARCH_PERF_H__ - -//#include - -#ifdef PERF -#define PERF_START { \ - unsigned long __c1l, __c1h, __c2l, __c2h; \ - __asm__(".byte 0x0f, 0x31" : "=a" (__c1l), "=d" (__c1h)) -#define PERF_STOP(x) __asm__(".byte 0x0f, 0x31" : "=a" (__c2l), "=d" (__c2h)); \ - perf_print(__c1l, __c1h, __c2l, __c2h, x);} - -/*#define PERF_START do { \ - struct tms __perf_start, __perf_end; \ - times(&__perf_start) -#define PERF_STOP(x) times(&__perf_end); \ - perf_print_times(&__perf_start, &__perf_end, x);\ - } while(0)*/ -#else /* PERF */ -#define PERF_START /* null definition */ -#define PERF_STOP(x) /* null definition */ -#endif /* PERF */ - -void perf_print(unsigned long c1l, unsigned long c1h, - unsigned long c2l, unsigned long c2h, - char *key); - -//void perf_print_times(struct tms *start, struct tms *end, char *key); - -//void perf_init(char *fname); - -#endif /* __ARCH_PERF_H__ */ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __ARCH_PERF_H__ +#define __ARCH_PERF_H__ + +//#include + +#ifdef PERF +#define PERF_START { \ + unsigned long __c1l, __c1h, __c2l, __c2h; \ + __asm__(".byte 0x0f, 0x31" : "=a" (__c1l), "=d" (__c1h)) +#define PERF_STOP(x) __asm__(".byte 0x0f, 0x31" : "=a" (__c2l), "=d" (__c2h)); \ + perf_print(__c1l, __c1h, __c2l, __c2h, x);} + +/*#define PERF_START do { \ + struct tms __perf_start, __perf_end; \ + times(&__perf_start) +#define PERF_STOP(x) times(&__perf_end); \ + perf_print_times(&__perf_start, &__perf_end, x);\ + } while(0)*/ +#else /* PERF */ +#define PERF_START /* null definition */ +#define PERF_STOP(x) /* null definition */ +#endif /* PERF */ + +void perf_print(unsigned long c1l, unsigned long c1h, + unsigned long c2l, unsigned long c2h, + char *key); + +//void perf_print_times(struct tms *start, struct tms *end, char *key); + +//void perf_init(char *fname); + +#endif /* __ARCH_PERF_H__ */ diff --git a/lwip/src/include/arch/sys_arch.h b/lwip/src/include/arch/sys_arch.h index f4b86339..fde4fbc2 100644 --- a/lwip/src/include/arch/sys_arch.h +++ b/lwip/src/include/arch/sys_arch.h @@ -1,52 +1,25 @@ #ifndef __ARCH_SYS_ARCH_H__ #define __ARCH_SYS_ARCH_H__ -#ifdef WIN32 - -#include -#include "../../../../mailbox.h" - -#else - #include #include +#include -#endif - -#ifdef WIN32 - -typedef bthread_mutex_t sys_mutex_t; - -typedef struct -{ - bthread_sem_t sem; - int valid; -}sys_sem_t; - -typedef struct -{ mailbox_ptr_t mailbox; - int valid; -}sys_mbox_t; -typedef bthread_t sys_thread_t; - -#else +#define EWOULDBLOCK EAGAIN /* Operation would block */ typedef sem_t sys_mutex_t; typedef struct { - sem_t sem; + sem_t sem; int valid; -}sys_sem_t; +} sys_sem_t; typedef struct -{ mailbox_ptr_t mailbox; - int valid; -}sys_mbox_t; +{ mailbox_ptr_t mailbox; + int valid; +} sys_mbox_t; typedef tid_t* sys_thread_t; -#endif - - -#endif /* __ARCH_SYS_ARCH_H__ */ \ No newline at end of file +#endif /* __ARCH_SYS_ARCH_H__ */ diff --git a/lwip/src/include/ipv4/lwip/icmp.h b/lwip/src/include/ipv4/lwip/icmp.h index c73961c9..d47a7d8a 100644 --- a/lwip/src/include/ipv4/lwip/icmp.h +++ b/lwip/src/include/ipv4/lwip/icmp.h @@ -41,29 +41,29 @@ extern "C" { #endif -#define ICMP_ER 0 /* echo reply */ -#define ICMP_DUR 3 /* destination unreachable */ -#define ICMP_SQ 4 /* source quench */ -#define ICMP_RD 5 /* redirect */ +#define ICMP_ER 0 /* echo reply */ +#define ICMP_DUR 3 /* destination unreachable */ +#define ICMP_SQ 4 /* source quench */ +#define ICMP_RD 5 /* redirect */ #define ICMP_ECHO 8 /* echo */ -#define ICMP_TE 11 /* time exceeded */ -#define ICMP_PP 12 /* parameter problem */ -#define ICMP_TS 13 /* timestamp */ +#define ICMP_TE 11 /* time exceeded */ +#define ICMP_PP 12 /* parameter problem */ +#define ICMP_TS 13 /* timestamp */ #define ICMP_TSR 14 /* timestamp reply */ #define ICMP_IRQ 15 /* information request */ -#define ICMP_IR 16 /* information reply */ +#define ICMP_IR 16 /* information reply */ enum icmp_dur_type { - ICMP_DUR_NET = 0, /* net unreachable */ - ICMP_DUR_HOST = 1, /* host unreachable */ + ICMP_DUR_NET = 0, /* net unreachable */ + ICMP_DUR_HOST = 1, /* host unreachable */ ICMP_DUR_PROTO = 2, /* protocol unreachable */ - ICMP_DUR_PORT = 3, /* port unreachable */ - ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */ - ICMP_DUR_SR = 5 /* source route failed */ + ICMP_DUR_PORT = 3, /* port unreachable */ + ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */ + ICMP_DUR_SR = 5 /* source route failed */ }; enum icmp_te_type { - ICMP_TE_TTL = 0, /* time to live exceeded in transit */ + ICMP_TE_TTL = 0, /* time to live exceeded in transit */ ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */ }; diff --git a/lwip/src/include/ipv4/lwip/ip.h b/lwip/src/include/ipv4/lwip/ip.h index 296e344b..74f501d1 100644 --- a/lwip/src/include/ipv4/lwip/ip.h +++ b/lwip/src/include/ipv4/lwip/ip.h @@ -122,10 +122,10 @@ struct ip_hdr { PACK_STRUCT_FIELD(u16_t _id); /* fragment offset field */ PACK_STRUCT_FIELD(u16_t _offset); -#define IP_RF 0x8000 /* reserved fragment flag */ -#define IP_DF 0x4000 /* dont fragment flag */ -#define IP_MF 0x2000 /* more fragments flag */ -#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ +#define IP_RF 0x8000U /* reserved fragment flag */ +#define IP_DF 0x4000U /* dont fragment flag */ +#define IP_MF 0x2000U /* more fragments flag */ +#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */ /* time to live */ PACK_STRUCT_FIELD(u8_t _ttl); /* protocol*/ diff --git a/lwip/src/include/lwip/err.h b/lwip/src/include/lwip/err.h index 2e34561d..ac907729 100644 --- a/lwip/src/include/lwip/err.h +++ b/lwip/src/include/lwip/err.h @@ -57,20 +57,19 @@ typedef s8_t err_t; #define ERR_INPROGRESS -5 /* Operation in progress */ #define ERR_VAL -6 /* Illegal value. */ #define ERR_WOULDBLOCK -7 /* Operation would block. */ +#define ERR_USE -8 /* Address in use. */ +#define ERR_ISCONN -9 /* Already connected. */ -#define ERR_IS_FATAL(e) ((e) < ERR_WOULDBLOCK) +#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN) -#define ERR_ABRT -8 /* Connection aborted. */ -#define ERR_RST -9 /* Connection reset. */ -#define ERR_CLSD -10 /* Connection closed. */ -#define ERR_CONN -11 /* Not connected. */ +#define ERR_ABRT -10 /* Connection aborted. */ +#define ERR_RST -11 /* Connection reset. */ +#define ERR_CLSD -12 /* Connection closed. */ +#define ERR_CONN -13 /* Not connected. */ -#define ERR_ARG -12 /* Illegal argument. */ +#define ERR_ARG -14 /* Illegal argument. */ -#define ERR_USE -13 /* Address in use. */ - -#define ERR_IF -14 /* Low-level netif error */ -#define ERR_ISCONN -15 /* Already connected. */ +#define ERR_IF -15 /* Low-level netif error */ #ifdef LWIP_DEBUG diff --git a/lwip/src/include/lwip/init.h b/lwip/src/include/lwip/init.h index 6ec541ef..77dcdfc7 100644 --- a/lwip/src/include/lwip/init.h +++ b/lwip/src/include/lwip/init.h @@ -47,7 +47,7 @@ extern "C" { /** For release candidates, this is set to 1..254 * For official releases, this is set to 255 (LWIP_RC_RELEASE) * For development versions (CVS), this is set to 0 (LWIP_RC_DEVELOPMENT) */ -#define LWIP_VERSION_RC 2U +#define LWIP_VERSION_RC 255U /** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */ #define LWIP_RC_RELEASE 255U diff --git a/lwip/src/include/lwip/mem.h b/lwip/src/include/lwip/mem.h index e7d8b8ba..9507c0ae 100644 --- a/lwip/src/include/lwip/mem.h +++ b/lwip/src/include/lwip/mem.h @@ -68,7 +68,7 @@ typedef size_t mem_size_t; /* MEM_SIZE would have to be aligned, but using 64000 here instead of * 65535 leaves some room for alignment... */ -#if MEM_SIZE > 64000l +#if MEM_SIZE > 64000L typedef u32_t mem_size_t; #define MEM_SIZE_F U32_F #else diff --git a/lwip/src/include/lwip/opt.h b/lwip/src/include/lwip/opt.h index c6d863e1..a1b87658 100644 --- a/lwip/src/include/lwip/opt.h +++ b/lwip/src/include/lwip/opt.h @@ -311,7 +311,7 @@ * (requires NO_SYS==0) */ #ifndef MEMP_NUM_SYS_TIMEOUT -#define MEMP_NUM_SYS_TIMEOUT 3000 +#define MEMP_NUM_SYS_TIMEOUT 3 #endif /** diff --git a/lwip/src/include/lwip/sys.h b/lwip/src/include/lwip/sys.h index 02025dbd..9f62c754 100644 --- a/lwip/src/include/lwip/sys.h +++ b/lwip/src/include/lwip/sys.h @@ -229,7 +229,6 @@ u32_t sys_jiffies(void); /** Returns the current time in milliseconds, * may be the same as sys_jiffies or at least based on it. */ - u32_t sys_now(void); /* Critical Region Protection */ diff --git a/lwip/src/include/lwip/tcp.h b/lwip/src/include/lwip/tcp.h index a09c5ef7..07dcd10e 100644 --- a/lwip/src/include/lwip/tcp.h +++ b/lwip/src/include/lwip/tcp.h @@ -228,7 +228,7 @@ struct tcp_pcb { u16_t acked; u16_t snd_buf; /* Available buffer space for sending (in bytes). */ -#define TCP_SNDQUEUELEN_OVERFLOW (0xffff-3) +#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */ #if TCP_OVERSIZE diff --git a/lwip/src/include/lwip/tcp_impl.h b/lwip/src/include/lwip/tcp_impl.h index 320b88ef..b4feec0d 100644 --- a/lwip/src/include/lwip/tcp_impl.h +++ b/lwip/src/include/lwip/tcp_impl.h @@ -278,7 +278,6 @@ PACK_STRUCT_END struct tcp_seg { struct tcp_seg *next; /* used when putting segements on a queue */ struct pbuf *p; /* buffer containing data + TCP header */ - void *dataptr; /* pointer to the TCP data in the pbuf */ u16_t len; /* the TCP length of this segment */ #if TCP_OVERSIZE_DBGCHECK u16_t oversize_left; /* Extra bytes available at the end of the last diff --git a/lwip/src/include/lwipopts.h b/lwip/src/include/lwipopts.h index 1048bb6d..af8d018c 100644 --- a/lwip/src/include/lwipopts.h +++ b/lwip/src/include/lwipopts.h @@ -1,71 +1,100 @@ -/* This file specifies the lwip features */ - -#ifndef __LWIPOPTS_H__ -#define __LWIPOPTS_H__ - - -/** - * NO_SYS==1: Provides VERY minimal functionality. Otherwise, - * use lwIP facilities. - */ -#define NO_SYS 0 - -/** - * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) - */ -#define LWIP_SOCKET 1 - -/** - * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) - */ -#define LWIP_NETCONN 1 - -/** - * LWIP_DHCP==1: Enable DHCP module. - */ -#define LWIP_DHCP 1 - -/** - * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. - */ -#define DHCP_DOES_ARP_CHECK 0 - -/** - * LWIP_TCP==1: Turn on TCP. - */ -#define LWIP_TCP 1 - -/** - * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) - */ -#define LWIP_BROADCAST_PING 1 - -/** - * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) - */ -#define LWIP_MULTICAST_PING 1 - -/** - * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c - */ -#define LWIP_HAVE_LOOPIF 1 - -/* DEBUG options */ -#define LWIP_DEBUG 0 -#define DHCP_DEBUG LWIP_DBG_OFF -#define ETHARP_DEBUG LWIP_DBG_OFF -#define TCPIP_DEBUG LWIP_DBG_OFF -#define SYS_DEBUG LWIP_DBG_OFF -#define RAW_DEBUG LWIP_DBG_OFF -#define MEM_DEBUG LWIP_DBG_OFF -#define IP_DEBUG LWIP_DBG_OFF -#define INET_DEBUG LWIP_DBG_OFF -#define NETIF_DEBUG LWIP_DBG_OFF - -#define TCP_SND_BUF 2048 - -#define LWIP_PROVIDE_ERRNO 1 - -#define TCP_SND_QUEUELEN 40 - -#endif +/* This file specifies the lwip features */ + +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H_ + +/** + * NO_SYS==1: Provides VERY minimal functionality. Otherwise, + * use lwIP facilities. + */ +#define NO_SYS 0 + +/** + * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) + */ +#define LWIP_SOCKET 1 + +/** + * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) + */ +#define LWIP_NETCONN 1 + +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#define LWIP_DHCP 1 + +/** + * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. + */ +#define DHCP_DOES_ARP_CHECK 0 + +/** + * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be + * updated with the source MAC and IP addresses supplied in the packet. + * You may want to disable this if you do not trust LAN peers to have the + * correct addresses, or as a limited approach to attempt to handle + * spoofing. If disabled, lwIP will need to make a new ARP request if + * the peer is not already in the ARP table, adding a little latency. + * The peer *is* in the ARP table if it requested our address before. + * Also notice that this slows down input processing of every IP packet! + */ +#define ETHARP_TRUST_IP_MAC 1 + +/** + * LWIP_TCP==1: Turn on TCP. + */ +#define LWIP_TCP 1 + +/** + * TCP_SND_BUF: TCP sender buffer space (bytes). + */ +#define TCP_SND_BUF 2048 + +/** + * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) + */ +#define LWIP_BROADCAST_PING 1 + +/** + * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) + */ +#define LWIP_MULTICAST_PING 1 + +/** + * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. + * (requires NO_SYS==0) + */ +#define MEMP_NUM_SYS_TIMEOUT 7 + +/** + * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c + */ +#define LWIP_HAVE_LOOPIF 1 + +/** + * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP + * address equal to the netif IP address, looping them back up the stack. + */ +#define LWIP_NETIF_LOOPBACK 1 + +/** + * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from + * application buffers to pbufs. + */ +#define LWIP_CHECKSUM_ON_COPY 1 + +/* DEBUG options */ +#define LWIP_DEBUG 1 +#define DHCP_DEBUG LWIP_DBG_OFF +#define ETHARP_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define SYS_DEBUG LWIP_DBG_ON +#define RAW_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_OFF +#define INET_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_ON +#define TIMERS_DEBUG LWIP_DBG_ON + +#endif diff --git a/lwip/src/include/netif/etharp.h b/lwip/src/include/netif/etharp.h index a4803ec4..691575fa 100644 --- a/lwip/src/include/netif/etharp.h +++ b/lwip/src/include/netif/etharp.h @@ -94,8 +94,8 @@ PACK_STRUCT_BEGIN * if 'type' in ethernet header is ETHTYPE_VLAN. * See IEEE802.Q */ struct eth_vlan_hdr { - PACK_STRUCT_FIELD(u16_t tpid); PACK_STRUCT_FIELD(u16_t prio_vid); + PACK_STRUCT_FIELD(u16_t tpid); } PACK_STRUCT_STRUCT; PACK_STRUCT_END #ifdef PACK_STRUCT_USE_INCLUDES @@ -134,11 +134,11 @@ PACK_STRUCT_END /** 5 seconds period */ #define ARP_TMR_INTERVAL 5000 -#define ETHTYPE_ARP 0x0806 -#define ETHTYPE_IP 0x0800 -#define ETHTYPE_VLAN 0x8100 -#define ETHTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */ -#define ETHTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */ +#define ETHTYPE_ARP 0x0806U +#define ETHTYPE_IP 0x0800U +#define ETHTYPE_VLAN 0x8100U +#define ETHTYPE_PPPOEDISC 0x8863U /* PPP Over Ethernet Discovery Stage */ +#define ETHTYPE_PPPOE 0x8864U /* PPP Over Ethernet Session Stage */ /** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables * or known to be 32-bit aligned within the protocol header. */ diff --git a/lwip/src/include/netif/loopif.h b/lwip/src/include/netif/loopif.h index 95b26315..304af4b3 100644 --- a/lwip/src/include/netif/loopif.h +++ b/lwip/src/include/netif/loopif.h @@ -1,53 +1,53 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __NETIF_LOOPIF_H__ -#define __NETIF_LOOPIF_H__ - -#include "lwip/opt.h" -#include "lwip/netif.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if !LWIP_NETIF_LOOPBACK_MULTITHREADING -#define loopif_poll netif_poll -#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ - -err_t loopif_init(struct netif *netif); - -#ifdef __cplusplus -} -#endif - -#endif /* __NETIF_LOOPIF_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __NETIF_LOOPIF_H__ +#define __NETIF_LOOPIF_H__ + +#include "lwip/opt.h" +#include "lwip/netif.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !LWIP_NETIF_LOOPBACK_MULTITHREADING +#define loopif_poll netif_poll +#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ + +err_t loopif_init(struct netif *netif); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETIF_LOOPIF_H__ */ diff --git a/lwip/src/netif/etharp.c b/lwip/src/netif/etharp.c index a6e2550b..b60dadd0 100644 --- a/lwip/src/netif/etharp.c +++ b/lwip/src/netif/etharp.c @@ -628,7 +628,7 @@ etharp_ip_input(struct netif *netif, struct pbuf *p) ethhdr = (struct eth_hdr *)p->payload; iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); #if ETHARP_SUPPORT_VLAN - if (ethhdr->type == ETHTYPE_VLAN) { + if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) { iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); } #endif /* ETHARP_SUPPORT_VLAN */ @@ -693,7 +693,7 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) ethhdr = (struct eth_hdr *)p->payload; hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); #if ETHARP_SUPPORT_VLAN - if (ethhdr->type == ETHTYPE_VLAN) { + if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) { hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); } #endif /* ETHARP_SUPPORT_VLAN */ @@ -702,11 +702,10 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) || (hdr->hwlen != ETHARP_HWADDR_LEN) || (hdr->protolen != sizeof(ip_addr_t)) || - (hdr->proto != PP_HTONS(ETHTYPE_IP)) || - (ethhdr->type != PP_HTONS(ETHTYPE_ARP))) { + (hdr->proto != PP_HTONS(ETHTYPE_IP))) { LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", - hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen, ethhdr->type)); + ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", + hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen)); ETHARP_STATS_INC(etharp.proterr); ETHARP_STATS_INC(etharp.drop); pbuf_free(p); @@ -1218,6 +1217,14 @@ ethernet_input(struct pbuf *p, struct netif *netif) { struct eth_hdr* ethhdr; u16_t type; + s16_t ip_hdr_offset = SIZEOF_ETH_HDR; + + if (p->len <= SIZEOF_ETH_HDR) { + /* a packet with only an ethernet header (or less) is not valid for us */ + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + goto free_and_return; + } /* points to packet payload, which starts with an Ethernet header */ ethhdr = (struct eth_hdr *)p->payload; @@ -1233,6 +1240,12 @@ ethernet_input(struct pbuf *p, struct netif *netif) #if ETHARP_SUPPORT_VLAN if (type == PP_HTONS(ETHTYPE_VLAN)) { struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR); + if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) { + /* a packet with only an ethernet/vlan header (or less) is not valid for us */ + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + goto free_and_return; + } #ifdef ETHARP_VLAN_CHECK /* if not, allow all VLANs */ if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) { /* silently ignore this packet: not for our VLAN */ @@ -1241,6 +1254,7 @@ ethernet_input(struct pbuf *p, struct netif *netif) } #endif /* ETHARP_VLAN_CHECK */ type = vlan->tpid; + ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR; } #endif /* ETHARP_SUPPORT_VLAN */ @@ -1260,7 +1274,7 @@ ethernet_input(struct pbuf *p, struct netif *netif) etharp_ip_input(netif, p); #endif /* ETHARP_TRUST_IP_MAC */ /* skip Ethernet header */ - if(pbuf_header(p, -(s16_t)SIZEOF_ETH_HDR)) { + if(pbuf_header(p, -ip_hdr_offset)) { LWIP_ASSERT("Can't move over header in packet", 0); goto free_and_return; } else { diff --git a/lwip/src/netif/loopif.c b/lwip/src/netif/loopif.c index 730ca85c..1e1f28cf 100644 --- a/lwip/src/netif/loopif.c +++ b/lwip/src/netif/loopif.c @@ -1,66 +1,66 @@ -/** - * @file - * Loop Interface - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#include "lwip/opt.h" - -#if LWIP_HAVE_LOOPIF - -#include "netif/loopif.h" -#include "lwip/snmp.h" - -/** - * Initialize a lwip network interface structure for a loopback interface - * - * @param netif the lwip network interface structure for this loopif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - */ -err_t -loopif_init(struct netif *netif) -{ - /* initialize the snmp variables and counters inside the struct netif - * ifSpeed: no assumption can be made! - */ - NETIF_INIT_SNMP(netif, snmp_ifType_softwareLoopback, 0); - - netif->name[0] = 'l'; - netif->name[1] = 'o'; - netif->output = netif_loop_output; - return ERR_OK; -} - -#endif /* LWIP_HAVE_LOOPIF */ +/** + * @file + * Loop Interface + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#include "lwip/opt.h" + +#if LWIP_HAVE_LOOPIF + +#include "netif/loopif.h" +#include "lwip/snmp.h" + +/** + * Initialize a lwip network interface structure for a loopback interface + * + * @param netif the lwip network interface structure for this loopif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + */ +err_t +loopif_init(struct netif *netif) +{ + /* initialize the snmp variables and counters inside the struct netif + * ifSpeed: no assumption can be made! + */ + NETIF_INIT_SNMP(netif, snmp_ifType_softwareLoopback, 0); + + netif->name[0] = 'l'; + netif->name[1] = 'o'; + netif->output = netif_loop_output; + return ERR_OK; +} + +#endif /* LWIP_HAVE_LOOPIF */ diff --git a/lwip/src/netif/ppp/ppp.c b/lwip/src/netif/ppp/ppp.c index fdf5e419..e9b433b0 100644 --- a/lwip/src/netif/ppp/ppp.c +++ b/lwip/src/netif/ppp/ppp.c @@ -344,7 +344,9 @@ static void pppRecvWakeup(int pd) { PPPDEBUG(LOG_DEBUG, ("pppRecvWakeup: unit %d\n", pd)); - sio_read_abort(pppControl[pd].fd); + if (pppControl[pd].openFlag != 0) { + sio_read_abort(pppControl[pd].fd); + } } #endif /* PPPOS_SUPPORT */ @@ -363,7 +365,6 @@ pppLinkTerminated(int pd) PPPControl* pc; pppRecvWakeup(pd); pc = &pppControl[pd]; - pppDrop(&pc->rx); /* bug fix #17726 */ PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); if (pc->linkStatusCB) { @@ -439,7 +440,7 @@ pppInit(void) magicInit(); - subnetMask = PP_HTONL(0xffffff00); + subnetMask = PP_HTONL(0xffffff00UL); for (i = 0; i < NUM_PPP; i++) { /* Initialize each protocol to the standard option set. */ @@ -681,20 +682,8 @@ pppClose(int pd) void pppSigHUP(int pd) { -#if PPPOE_SUPPORT - PPPControl *pc = &pppControl[pd]; - if(pc->ethif) { - PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd)); - pppHup(pd); - } else -#endif /* PPPOE_SUPPORT */ - { -#if PPPOS_SUPPORT - PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd)); - pppHup(pd); - pppRecvWakeup(pd); -#endif /* PPPOS_SUPPORT */ - } + PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd)); + pppHup(pd); } #if PPPOS_SUPPORT @@ -1809,6 +1798,7 @@ pppInProc(PPPControlRx *pcrx, u_char *s, int l) pppDrop(pcrx); /* Otherwise it's a good packet so pass it on. */ } else { + struct pbuf *inp; /* Trim off the checksum. */ if(pcrx->inTail->len >= 2) { pcrx->inTail->len -= 2; @@ -1827,18 +1817,20 @@ pppInProc(PPPControlRx *pcrx, u_char *s, int l) } /* Dispatch the packet thereby consuming it. */ + inp = pcrx->inHead; + /* Packet consumed, release our references. */ + pcrx->inHead = NULL; + pcrx->inTail = NULL; #if PPP_INPROC_MULTITHREADED - if(tcpip_callback_with_block(pppInput, pcrx->inHead, 0) != ERR_OK) { + if(tcpip_callback_with_block(pppInput, inp, 0) != ERR_OK) { PPPDEBUG(LOG_ERR, ("pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd)); - pbuf_free(pcrx->inHead); + pbuf_free(inp); LINK_STATS_INC(link.drop); snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); } #else /* PPP_INPROC_MULTITHREADED */ - pppInput(pcrx->inHead); + pppInput(inp); #endif /* PPP_INPROC_MULTITHREADED */ - pcrx->inHead = NULL; - pcrx->inTail = NULL; } /* Prepare for a new packet. */ @@ -1912,10 +1904,12 @@ pppInProc(PPPControlRx *pcrx, u_char *s, int l) case PDDATA: /* Process data byte. */ /* Make space to receive processed data. */ if (pcrx->inTail == NULL || pcrx->inTail->len == PBUF_POOL_BUFSIZE) { - if(pcrx->inTail) { + if (pcrx->inTail != NULL) { pcrx->inTail->tot_len = pcrx->inTail->len; if (pcrx->inTail != pcrx->inHead) { pbuf_cat(pcrx->inHead, pcrx->inTail); + /* give up the inTail reference now */ + pcrx->inTail = NULL; } } /* If we haven't started a packet, we need a packet header. */ diff --git a/lwip/test/unit/etharp/test_etharp.c b/lwip/test/unit/etharp/test_etharp.c index 7eedc764..207d73fd 100644 --- a/lwip/test/unit/etharp/test_etharp.c +++ b/lwip/test/unit/etharp/test_etharp.c @@ -90,7 +90,8 @@ create_arp_response(ip_addr_t *adr) etharphdr->hwtype = htons(/*HWTYPE_ETHERNET*/ 1); etharphdr->proto = htons(ETHTYPE_IP); - etharphdr->_hwlen_protolen = htons((ETHARP_HWADDR_LEN << 8) | sizeof(ip_addr_t)); + etharphdr->hwlen = ETHARP_HWADDR_LEN; + etharphdr->protolen = sizeof(ip_addr_t); etharphdr->opcode = htons(ARP_REPLY); SMEMCPY(ðarphdr->sipaddr, adr, sizeof(ip_addr_t)); diff --git a/lwip/test/unit/tcp/tcp_helper.c b/lwip/test/unit/tcp/tcp_helper.c index bccc69dd..b2825408 100644 --- a/lwip/test/unit/tcp/tcp_helper.c +++ b/lwip/test/unit/tcp/tcp_helper.c @@ -88,7 +88,8 @@ tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip, memcpy((char*)tcphdr + sizeof(struct tcp_hdr), data, data_len); /* calculate checksum */ - tcphdr->chksum = inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), + + tcphdr->chksum = inet_chksum_pseudo(p, src_ip, dst_ip, IP_PROTO_TCP, p->tot_len); pbuf_header(p, sizeof(struct ip_hdr)); @@ -193,3 +194,20 @@ test_tcp_new_counters_pcb(struct test_tcp_counters* counters) } return pcb; } + +/** Calls tcp_input() after adjusting current_iphdr_dest */ +void test_tcp_input(struct pbuf *p, struct netif *inp) +{ + struct ip_hdr *iphdr = (struct ip_hdr*)p->payload; + ip_addr_copy(current_iphdr_dest, iphdr->dest); + ip_addr_copy(current_iphdr_src, iphdr->src); + current_netif = inp; + current_header = iphdr; + + tcp_input(p, inp); + + current_iphdr_dest.addr = 0; + current_iphdr_src.addr = 0; + current_netif = NULL; + current_header = NULL; +} diff --git a/lwip/test/unit/tcp/tcp_helper.h b/lwip/test/unit/tcp/tcp_helper.h index 2bf6d73f..af546dc6 100644 --- a/lwip/test/unit/tcp/tcp_helper.h +++ b/lwip/test/unit/tcp/tcp_helper.h @@ -33,4 +33,6 @@ err_t test_tcp_counters_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err struct tcp_pcb* test_tcp_new_counters_pcb(struct test_tcp_counters* counters); +void test_tcp_input(struct pbuf *p, struct netif *inp); + #endif diff --git a/lwip/test/unit/tcp/test_tcp.c b/lwip/test/unit/tcp/test_tcp.c index 50498ea9..0eec3cca 100644 --- a/lwip/test/unit/tcp/test_tcp.c +++ b/lwip/test/unit/tcp/test_tcp.c @@ -76,7 +76,7 @@ START_TEST(test_tcp_recv_inseq) EXPECT(p != NULL); if (p != NULL) { /* pass the segment to tcp_input */ - tcp_input(p, &netif); + test_tcp_input(p, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 1); diff --git a/lwip/test/unit/tcp/test_tcp_oos.c b/lwip/test/unit/tcp/test_tcp_oos.c index 8f90fff1..56944e20 100644 --- a/lwip/test/unit/tcp/test_tcp_oos.c +++ b/lwip/test/unit/tcp/test_tcp_oos.c @@ -180,7 +180,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) EXPECT(p_fin != NULL); if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) { /* pass the segment to tcp_input */ - tcp_input(p_8_9, &netif); + test_tcp_input(p_8_9, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -192,7 +192,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */ /* pass the segment to tcp_input */ - tcp_input(p_4_8, &netif); + test_tcp_input(p_4_8, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -206,7 +206,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */ /* pass the segment to tcp_input */ - tcp_input(p_4_10, &netif); + test_tcp_input(p_4_10, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -220,7 +220,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */ /* pass the segment to tcp_input */ - tcp_input(p_2_14, &netif); + test_tcp_input(p_2_14, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -232,7 +232,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */ /* pass the segment to tcp_input */ - tcp_input(p_fin, &netif); + test_tcp_input(p_fin, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -244,7 +244,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */ /* pass the segment to tcp_input */ - tcp_input(pinseq, &netif); + test_tcp_input(pinseq, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 1); EXPECT(counters.recv_calls == 1); @@ -330,7 +330,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL) && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) { /* pass the segment to tcp_input */ - tcp_input(p_1_2, &netif); + test_tcp_input(p_1_2, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -342,7 +342,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2); /* pass the segment to tcp_input */ - tcp_input(p_4_8, &netif); + test_tcp_input(p_4_8, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -356,7 +356,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8); /* pass the segment to tcp_input */ - tcp_input(p_3_11, &netif); + test_tcp_input(p_3_11, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -371,7 +371,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11); /* pass the segment to tcp_input */ - tcp_input(p_2_12, &netif); + test_tcp_input(p_2_12, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -385,7 +385,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12); /* pass the segment to tcp_input */ - tcp_input(pinseq, &netif); + test_tcp_input(pinseq, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 1); @@ -394,7 +394,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT(pcb->ooseq == NULL); /* pass the segment to tcp_input */ - tcp_input(p_15_1, &netif); + test_tcp_input(p_15_1, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 1); @@ -406,7 +406,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); /* pass the segment to tcp_input */ - tcp_input(p_15_1a, &netif); + test_tcp_input(p_15_1a, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 1); @@ -418,7 +418,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); /* pass the segment to tcp_input */ - tcp_input(pinseqFIN, &netif); + test_tcp_input(pinseqFIN, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 1); EXPECT(counters.recv_calls == 2); @@ -480,7 +480,7 @@ START_TEST(test_tcp_recv_ooseq_overrun_rxwin) TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); EXPECT(p != NULL); /* pass the segment to tcp_input */ - tcp_input(p, &netif); + test_tcp_input(p, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -504,7 +504,7 @@ START_TEST(test_tcp_recv_ooseq_overrun_rxwin) p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); EXPECT(p_ovr != NULL); /* pass the segment to tcp_input */ - tcp_input(p_ovr, &netif); + test_tcp_input(p_ovr, &netif); /* check if counters are as expected */ EXPECT(counters.close_calls == 0); EXPECT(counters.recv_calls == 0); @@ -516,7 +516,7 @@ START_TEST(test_tcp_recv_ooseq_overrun_rxwin) EXPECT_OOSEQ(datalen == datalen2); /* now pass inseq */ - tcp_input(pinseq, &netif); + test_tcp_input(pinseq, &netif); EXPECT(pcb->ooseq == NULL); /* make sure the pcb is freed */ diff --git a/mm/memory.c b/mm/memory.c index c6241d52..ad29aedd 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -39,7 +39,7 @@ * * Set whole address space as occupied */ -static uint8_t bitmap[BITMAP_SIZE] = {[0 ... BITMAP_SIZE-1] = 0xFF}; +static uint8_t bitmap[BITMAP_SIZE]; // = {[0 ... BITMAP_SIZE-1] = 0xFF}; static spinlock_t bitmap_lock = SPINLOCK_INIT; static size_t alloc_start; atomic_int32_t total_pages = ATOMIC_INIT(0); @@ -94,6 +94,9 @@ int mmu_init(void) unsigned int i; size_t addr; + // at first, set default value of the bitmap + memset(bitmap, 0xFF, sizeof(uint8_t)*BITMAP_SIZE); + #ifdef CONFIG_MULTIBOOT if (mb_info && (mb_info->flags & MULTIBOOT_INFO_MEM_MAP)) { size_t end_addr; diff --git a/newlib/src/compile b/newlib/src/compile old mode 100644 new mode 100755 diff --git a/newlib/src/config.guess b/newlib/src/config.guess old mode 100644 new mode 100755 diff --git a/newlib/src/config.rpath b/newlib/src/config.rpath old mode 100644 new mode 100755 diff --git a/newlib/src/config.status b/newlib/src/config.status old mode 100644 new mode 100755 diff --git a/newlib/src/config.sub b/newlib/src/config.sub old mode 100644 new mode 100755 diff --git a/newlib/src/config/acinclude.m4 b/newlib/src/config/acinclude.m4 old mode 100644 new mode 100755 diff --git a/newlib/src/depcomp b/newlib/src/depcomp old mode 100644 new mode 100755 diff --git a/newlib/src/etc/config.status b/newlib/src/etc/config.status old mode 100644 new mode 100755 diff --git a/newlib/src/etc/configure b/newlib/src/etc/configure old mode 100644 new mode 100755 diff --git a/newlib/src/install-sh b/newlib/src/install-sh old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/bfin/configure b/newlib/src/libgloss/bfin/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/configure b/newlib/src/libgloss/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/cris/configure b/newlib/src/libgloss/cris/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/crx/configure b/newlib/src/libgloss/crx/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/d30v/configure b/newlib/src/libgloss/d30v/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/doc/configure b/newlib/src/libgloss/doc/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/fr30/configure b/newlib/src/libgloss/fr30/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/frv/configure b/newlib/src/libgloss/frv/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/hp74x/configure b/newlib/src/libgloss/hp74x/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/i386/configure b/newlib/src/libgloss/i386/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/i960/configure b/newlib/src/libgloss/i960/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/iq2000/configure b/newlib/src/libgloss/iq2000/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/libnosys/configure b/newlib/src/libgloss/libnosys/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/lm32/configure b/newlib/src/libgloss/lm32/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/m32c/configure b/newlib/src/libgloss/m32c/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/m32r/configure b/newlib/src/libgloss/m32r/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/m68hc11/configure b/newlib/src/libgloss/m68hc11/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/m68k/configure b/newlib/src/libgloss/m68k/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/mcore/configure b/newlib/src/libgloss/mcore/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/mep/configure b/newlib/src/libgloss/mep/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/metalsvm/configure b/newlib/src/libgloss/metalsvm/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/mips/configure b/newlib/src/libgloss/mips/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/mn10200/configure b/newlib/src/libgloss/mn10200/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/mn10300/configure b/newlib/src/libgloss/mn10300/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/mt/configure b/newlib/src/libgloss/mt/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/pa/configure b/newlib/src/libgloss/pa/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/rs6000/configure b/newlib/src/libgloss/rs6000/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/sparc/configure b/newlib/src/libgloss/sparc/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/sparc/libsys/configure b/newlib/src/libgloss/sparc/libsys/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/tic6x/configure b/newlib/src/libgloss/tic6x/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/wince/configure b/newlib/src/libgloss/wince/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/xc16x/configure b/newlib/src/libgloss/xc16x/configure old mode 100644 new mode 100755 diff --git a/newlib/src/libgloss/xstormy16/configure b/newlib/src/libgloss/xstormy16/configure old mode 100644 new mode 100755 diff --git a/newlib/src/missing b/newlib/src/missing old mode 100644 new mode 100755 diff --git a/newlib/src/mkdep b/newlib/src/mkdep old mode 100644 new mode 100755 diff --git a/newlib/src/mkinstalldirs b/newlib/src/mkinstalldirs old mode 100644 new mode 100755 diff --git a/newlib/src/move-if-change b/newlib/src/move-if-change old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/configure b/newlib/src/newlib/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/doc/configure b/newlib/src/newlib/doc/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/iconvdata/configure b/newlib/src/newlib/iconvdata/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/configure b/newlib/src/newlib/libc/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/iconv/ccs/mktbl.pl b/newlib/src/newlib/libc/iconv/ccs/mktbl.pl old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/iconv/ces/mkdeps.pl b/newlib/src/newlib/libc/iconv/ces/mkdeps.pl old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/a29k/configure b/newlib/src/newlib/libc/machine/a29k/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/arm/configure b/newlib/src/newlib/libc/machine/arm/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/bfin/configure b/newlib/src/newlib/libc/machine/bfin/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/configure b/newlib/src/newlib/libc/machine/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/cris/configure b/newlib/src/newlib/libc/machine/cris/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/crx/configure b/newlib/src/newlib/libc/machine/crx/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/d10v/configure b/newlib/src/newlib/libc/machine/d10v/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/d30v/configure b/newlib/src/newlib/libc/machine/d30v/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/fr30/configure b/newlib/src/newlib/libc/machine/fr30/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/frv/configure b/newlib/src/newlib/libc/machine/frv/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/h8300/configure b/newlib/src/newlib/libc/machine/h8300/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/h8500/configure b/newlib/src/newlib/libc/machine/h8500/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/hppa/configure b/newlib/src/newlib/libc/machine/hppa/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/i386/configure b/newlib/src/newlib/libc/machine/i386/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/i960/configure b/newlib/src/newlib/libc/machine/i960/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/iq2000/configure b/newlib/src/newlib/libc/machine/iq2000/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/lm32/configure b/newlib/src/newlib/libc/machine/lm32/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/m32c/configure b/newlib/src/newlib/libc/machine/m32c/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/m32r/configure b/newlib/src/newlib/libc/machine/m32r/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/m68hc11/configure b/newlib/src/newlib/libc/machine/m68hc11/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/m68k/configure b/newlib/src/newlib/libc/machine/m68k/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/m88k/configure b/newlib/src/newlib/libc/machine/m88k/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/mep/configure b/newlib/src/newlib/libc/machine/mep/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/mips/configure b/newlib/src/newlib/libc/machine/mips/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/mn10200/configure b/newlib/src/newlib/libc/machine/mn10200/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/mn10300/configure b/newlib/src/newlib/libc/machine/mn10300/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/mt/configure b/newlib/src/newlib/libc/machine/mt/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/necv70/configure b/newlib/src/newlib/libc/machine/necv70/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/powerpc/configure b/newlib/src/newlib/libc/machine/powerpc/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/rx/configure b/newlib/src/newlib/libc/machine/rx/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/sh/configure b/newlib/src/newlib/libc/machine/sh/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/sparc/configure b/newlib/src/newlib/libc/machine/sparc/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/tic4x/configure b/newlib/src/newlib/libc/machine/tic4x/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/tic6x/configure b/newlib/src/newlib/libc/machine/tic6x/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/tic80/configure b/newlib/src/newlib/libc/machine/tic80/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/v850/configure b/newlib/src/newlib/libc/machine/v850/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/w65/configure b/newlib/src/newlib/libc/machine/w65/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/w65/lshrhi.S b/newlib/src/newlib/libc/machine/w65/lshrhi.S old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/w65/sdivhi3.S b/newlib/src/newlib/libc/machine/w65/sdivhi3.S old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/w65/smulhi3.S b/newlib/src/newlib/libc/machine/w65/smulhi3.S old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/w65/udivhi3.S b/newlib/src/newlib/libc/machine/w65/udivhi3.S old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/w65/umodhi3.S b/newlib/src/newlib/libc/machine/w65/umodhi3.S old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/x86_64/configure b/newlib/src/newlib/libc/machine/x86_64/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/xscale/configure b/newlib/src/newlib/libc/machine/xscale/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/xstormy16/configure b/newlib/src/newlib/libc/machine/xstormy16/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/machine/z8k/configure b/newlib/src/newlib/libc/machine/z8k/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/a29khif/configure b/newlib/src/newlib/libc/sys/a29khif/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/arc/configure b/newlib/src/newlib/libc/sys/arc/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/arm/configure b/newlib/src/newlib/libc/sys/arm/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/configure b/newlib/src/newlib/libc/sys/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/d10v/configure b/newlib/src/newlib/libc/sys/d10v/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/decstation/configure b/newlib/src/newlib/libc/sys/decstation/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/h8300hms/configure b/newlib/src/newlib/libc/sys/h8300hms/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/h8500hms/configure b/newlib/src/newlib/libc/sys/h8500hms/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/linux/configure b/newlib/src/newlib/libc/sys/linux/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/linux/linuxthreads/configure b/newlib/src/newlib/libc/sys/linux/linuxthreads/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/linux/linuxthreads/machine/configure b/newlib/src/newlib/libc/sys/linux/linuxthreads/machine/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/linux/linuxthreads/machine/i386/configure b/newlib/src/newlib/libc/sys/linux/linuxthreads/machine/i386/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/linux/machine/configure b/newlib/src/newlib/libc/sys/linux/machine/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/linux/machine/i386/configure b/newlib/src/newlib/libc/sys/linux/machine/i386/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/m88kbug/configure b/newlib/src/newlib/libc/sys/m88kbug/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/mmixware/configure b/newlib/src/newlib/libc/sys/mmixware/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/netware/configure b/newlib/src/newlib/libc/sys/netware/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/rdos/chown.c b/newlib/src/newlib/libc/sys/rdos/chown.c old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/rdos/configure b/newlib/src/newlib/libc/sys/rdos/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/rdos/fork.c b/newlib/src/newlib/libc/sys/rdos/fork.c old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/rdos/fstat.c b/newlib/src/newlib/libc/sys/rdos/fstat.c old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/rdos/lseek.c b/newlib/src/newlib/libc/sys/rdos/lseek.c old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/rdos/open.c b/newlib/src/newlib/libc/sys/rdos/open.c old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/rdos/rdos.h b/newlib/src/newlib/libc/sys/rdos/rdos.h old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/rdos/readlink.c b/newlib/src/newlib/libc/sys/rdos/readlink.c old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/rdos/stat.c b/newlib/src/newlib/libc/sys/rdos/stat.c old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/rdos/symlink.c b/newlib/src/newlib/libc/sys/rdos/symlink.c old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/rtems/configure b/newlib/src/newlib/libc/sys/rtems/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/sh/configure b/newlib/src/newlib/libc/sys/sh/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/sparc64/configure b/newlib/src/newlib/libc/sys/sparc64/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/sun4/configure b/newlib/src/newlib/libc/sys/sun4/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/sysmec/configure b/newlib/src/newlib/libc/sys/sysmec/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/sysnec810/configure b/newlib/src/newlib/libc/sys/sysnec810/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/sysnecv850/configure b/newlib/src/newlib/libc/sys/sysnecv850/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/sysvi386/configure b/newlib/src/newlib/libc/sys/sysvi386/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/sysvnecv70/configure b/newlib/src/newlib/libc/sys/sysvnecv70/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/tic80/configure b/newlib/src/newlib/libc/sys/tic80/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/w65/configure b/newlib/src/newlib/libc/sys/w65/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libc/sys/z8ksim/configure b/newlib/src/newlib/libc/sys/z8ksim/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libm/configure b/newlib/src/newlib/libm/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libm/machine/configure b/newlib/src/newlib/libm/machine/configure old mode 100644 new mode 100755 diff --git a/newlib/src/newlib/libm/machine/i386/configure b/newlib/src/newlib/libm/machine/i386/configure old mode 100644 new mode 100755 diff --git a/newlib/src/symlink-tree b/newlib/src/symlink-tree old mode 100644 new mode 100755 diff --git a/newlib/src/ylwrap b/newlib/src/ylwrap old mode 100644 new mode 100755 diff --git a/tools/bootinfo.sh b/tools/bootinfo.sh old mode 100644 new mode 100755 diff --git a/tools/prepare.sh b/tools/prepare.sh old mode 100644 new mode 100755